国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android實現文本排版

2019-12-12 06:34:25
字體:
來源:轉載
供稿:網友

  在項目中有一個小功能需要實現,就是對多行文本進行排版布局,每一行的內容又分為兩部分,左邊為標題,右邊為描述,左邊內容長度不確定,右邊的內容需要對齊,如有換行也需要對齊右邊的文本。

一、效果圖

       

可以看到內容分成了兩部分,左邊的顏色與右邊不一致,右邊的描述文案統一對齊。

二、實現方案

       以上功能,由于輸入內容輸入行數不確定,并且左邊的文案長度也不確定,因此不能直接在布局中實現,基于此這里主要實現了以下6種方式

方案1

       采用自定義控件的方式,繼承TextView,重新onDraw函數,實現如下:

/** * 計算出左邊最長的顯示字符串maxLeftWidth,之后draw每一行字符,右邊的描述從maxLeftWidth開始draw * 當一行顯示不完全時,折行并且空出maxLeftWidth的空格長度 */public class TypographyView1 extends TextView {  private Paint leftPaint = new Paint();  private Paint rightPaint = new Paint();  private int fullWidth;  private float textSize;  private JSONArray array;  private int middlePadding = 0;  float maxLeftWidth = 0;  int itemSize = 0;  public TypographyView1(Context context) {    super(context);    init();  }  public TypographyView1(Context context, AttributeSet attrs) {    super(context, attrs);    init();  }  public TypographyView1(Context context, AttributeSet attrs, int defStyleAttr) {    super(context, attrs, defStyleAttr);    init();  }  private void init() {    textSize = getResources().getDimensionPixelSize(R.dimen.text_size_13);    leftPaint.setAntiAlias(true);    leftPaint.setTextSize(textSize);    leftPaint.setColor(getResources().getColor(R.color.color_black_999999));    rightPaint.setAntiAlias(true);    rightPaint.setTextSize(textSize);    rightPaint.setColor(getResources().getColor(R.color.color_black));    middlePadding = getResources().getDimensionPixelSize(R.dimen.padding_value);  }  @Override  protected void onSizeChanged(int w, int h, int oldw, int oldh) {    super.onSizeChanged(w, h, oldw, oldh);    fullWidth = getWidth();// 整個textView的寬度  }  public void setText(JSONArray array) {    this.array = array;    if (array != null) {      try {        int size = itemSize = array.length();        for (int i = 0; i < size; ++i) {          JSONArray o = (JSONArray) array.get(i);          String key = o.getString(0);          String value = o.getString(1);          if (TextUtils.isEmpty(key) || TextUtils.isEmpty(value)) {            itemSize--;            continue;          }          float curWidth = leftPaint.measureText(key);          if (curWidth > maxLeftWidth) {            maxLeftWidth = curWidth;          }        }        maxLeftWidth = maxLeftWidth + middlePadding;        invalidate();      } catch (Exception e) {      }    }  }  boolean setHeight = false;  @Override  protected void onDraw(Canvas canvas) {    if (array == null) {      return;    }    int lineCount = 0;    try {      JSONArray item;      float offsetY;      for (int i = 0; i < itemSize; ++i) {        item = (JSONArray) array.get(i);        offsetY = (lineCount + 1) * textSize;        canvas.drawText(item.getString(0), 0, offsetY, leftPaint);        String value = item.getString(1);        float valueWidth = rightPaint.measureText(value);        if (valueWidth > fullWidth - maxLeftWidth) {// 一行顯示不完          char[] textCharArray = value.toCharArray();          float charWidth;          float drawWidth = maxLeftWidth;          for (int j = 0; j < textCharArray.length; j++) {            charWidth = rightPaint.measureText(textCharArray, j, 1);            if (fullWidth - drawWidth < charWidth) {              lineCount++;              drawWidth = maxLeftWidth;              offsetY += textSize;            }            canvas.drawText(textCharArray, j, 1, drawWidth, offsetY, rightPaint);            drawWidth += charWidth;          }        } else {          canvas.drawText(value, maxLeftWidth, offsetY, rightPaint);        }        lineCount += 2;      }      if (!setHeight) {        setHeight((lineCount + 1) * (int) textSize);        setHeight = true;      }    } catch (JSONException e) {      e.printStackTrace();    }  }}

       添加了setText(JSONArray array)作為數據輸入,并且在這里面測量了左邊title的最大寬度,之后調用invalidate觸發重繪,在onSizeChanged獲取整個控件的寬度,重繪會調用onDraw函數,這里不需要調用super函數,TextView的onDraw函數做了非常多的操作,解析傳入的數據,分別一行一行調用canvas來進行drawText操作,當繪制描述時,先計算寬度,如果超過剩余控件說明需要換行,最后調用setHeight設置高度,這個加一個判斷條件,因為會觸發requestLayout()進行重新布局和invalidate()進行重繪,如果不加判斷會一直重繪。

方案2

       方式2與方式1差不多,不同為所有計算都在onDraw函數中:

/** * 該方式與方式1很類似,只是所有的計算都放在了onDraw方法中。 */public class TypographyView2 extends TextView {  private Paint paint1 = new Paint();  private Paint paint2 = new Paint();  private int middlePadding = 0;  int width;  private float textSize;  private JSONArray array;  public TypographyView2(Context context) {    super(context);    init();  }  public TypographyView2(Context context, AttributeSet attrs) {    super(context, attrs);    init();  }  public TypographyView2(Context context, AttributeSet attrs, int defStyleAttr) {    super(context, attrs, defStyleAttr);    init();  }  private void init() {    textSize = getResources().getDimensionPixelSize(R.dimen.text_size_13);    paint1.setAntiAlias(true);    paint1.setTextSize(textSize);    paint1.setColor(getResources().getColor(R.color.color_black_999999));    paint2.setAntiAlias(true);    paint2.setTextSize(textSize);    paint2.setColor(getResources().getColor(R.color.color_black));    middlePadding = getResources().getDimensionPixelSize(R.dimen.padding_value);  }  @Override  protected void onSizeChanged(int w, int h, int oldw, int oldh) {    super.onSizeChanged(w, h, oldw, oldh);    width = getWidth();// 整個textView的寬度  }  public void setText(JSONArray array) {    this.array = array;    if (array != null) {      invalidate();    }  }  boolean setHeight = false;  @Override  protected void onDraw(Canvas canvas) {    // super.onDraw(canvas);    int lineCount = 0;    int size = array.length();    float maxLeftWidth = 0;    float drawWidth = 0;    try {      for (int i = 0; i < size; ++i) {        JSONArray o = (JSONArray) array.get(i);        String key = o.getString(0);        float v = paint1.measureText(key);        if (v > maxLeftWidth) {          maxLeftWidth = v;        }      }      maxLeftWidth = maxLeftWidth + middlePadding;      for (int i = 0; i < size; ++i) {        JSONArray o = (JSONArray) array.get(i);        String key = o.getString(0);        canvas.drawText(key, 0, (lineCount + 1) * textSize, paint1);        String value = o.getString(1);        char[] textCharArray = value.toCharArray();        float charWidth;        drawWidth = maxLeftWidth;        for (int j = 0; j < textCharArray.length; j++) {          charWidth = paint1.measureText(textCharArray, j, 1);          if (width - drawWidth < charWidth) {            lineCount++;            drawWidth = maxLeftWidth;          }          canvas.drawText(textCharArray, j, 1, drawWidth, (lineCount + 1) * textSize, paint2);          drawWidth += charWidth;        }        lineCount += 2;      }      if (!setHeight) {        setHeight((lineCount + 1) * (int) textSize + 5);        setHeight = true;      }    } catch (JSONException e) {      e.printStackTrace();    }  }}

       該方案的實現是不太好的,方案1也是在此基礎上進行調整的,在這里放出來只是為了說明,所有的計算不要全部放在onDraw里面,因為該方法可能會反復調用多次,這樣就降低了性能。

方案3

       將數據源拼接成SpannableString,重寫onDraw函數,根據內容draw每一個字符:

/** * 該方法,是需要顯示的內容先拼接成SpannableString,在onDraw方法中獲取所有的char字符,一個一個比較 * 當為分號是,表示為key與value的分隔符。 */public class TypographyView3 extends TextView {  private Paint leftPaint = new Paint();  private Paint rightPaint = new Paint();  int width;  private String text;  private float textSize;  float maxLeftWidth = 0;  private int middlePadding = 0;  public TypographyView3(Context context) {    super(context);    init();  }  public TypographyView3(Context context, AttributeSet attrs) {    super(context, attrs);    init();  }  public TypographyView3(Context context, AttributeSet attrs, int defStyleAttr) {    super(context, attrs, defStyleAttr);    init();  }  private void init() {    textSize = getResources().getDimensionPixelSize(R.dimen.text_size_13);    textSize = getResources().getDimensionPixelSize(R.dimen.text_size_13);    leftPaint.setAntiAlias(true);    leftPaint.setTextSize(textSize);    leftPaint.setColor(getResources().getColor(R.color.color_black_999999));    rightPaint.setAntiAlias(true);    rightPaint.setTextSize(textSize);    rightPaint.setColor(getResources().getColor(R.color.color_black));    middlePadding = getResources().getDimensionPixelSize(R.dimen.padding_value);  }  @Override  protected void onSizeChanged(int w, int h, int oldw, int oldh) {    super.onSizeChanged(w, h, oldw, oldh);    width = getWidth();// 整個textView的寬度  }  public void setText(JSONArray data) {    if (data == null) {      return;    }    try {      int size = data.length();      for (int i = 0; i < size; ++i) {        JSONArray o = (JSONArray) data.get(i);        String key = o.getString(0);        float v = leftPaint.measureText(key);        if (v > maxLeftWidth) {          maxLeftWidth = v;        }      }      maxLeftWidth += middlePadding;      SpannableStringBuilder ssb = new SpannableStringBuilder();      for (int i = 0; i < size; ++i) {        addItem((JSONArray) data.get(i), ssb, i != 0);      }      setText(ssb, BufferType.SPANNABLE);    } catch (Exception e) {    }  }  private void addItem(JSONArray item, SpannableStringBuilder ssb, boolean breakLine) {    try {      if (item == null || item.length() == 0) {        return;      }      String key = item.getString(0);      String value = (item.length() >= 2) ? item.getString(1) : "";      if (TextUtils.isEmpty(key) && TextUtils.isEmpty(value)) {        return;      }      if (breakLine) {// 換行        ssb.append("/r/n");        ssb.append("/r/n");      }      SpannableString span = new SpannableString(key);      //      span.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.colorAccent)), 0, key      // .length(),      //          Spanned.SPAN_INCLUSIVE_EXCLUSIVE);      ssb.append(span);      ssb.append(value);    } catch (JSONException e) {      e.printStackTrace();    }  }  @Override  protected void onDraw(Canvas canvas) {    // super.onDraw(canvas);    int lineCount = 0;    text = this.getText().toString();    if (text == null)      return;    char[] textCharArray = text.toCharArray();    // 已繪的寬度    float drawWidth = 0;    float charWidth;    Paint paint = leftPaint;    for (int i = 0; i < textCharArray.length; i++) {      charWidth = leftPaint.measureText(textCharArray, i, 1);      if (textCharArray[i] == '/n') {        lineCount++;        drawWidth = 0;        paint = leftPaint;        continue;      }      if (width - drawWidth < charWidth) {        lineCount++;        drawWidth = maxLeftWidth;      }      if (i > 1 && textCharArray[i - 1] == ':') {        drawWidth = maxLeftWidth;        paint = rightPaint;      }      canvas.drawText(textCharArray, i, 1, drawWidth, (lineCount + 1) * textSize, paint);      drawWidth += charWidth;    }    //may be need set height    //setHeight((lineCount + 1) * (int) textSize + 5);  }}

       這里先計算左邊title的最大寬度,同時將所有的數據拼接成一個SpannableStringBuilder,調用setText函數會觸發重繪,在onDraw函數中進行處理,由于未重新super函數,因此SpannableString的setSpan函數失效,該方案主要根據分隔符來進行分割,因此分隔符需要唯一。

方案4

       采用GridLayout方式實現,但是原始控件有展示問題,因此對此進行了修改:

public class Typography4Activity extends BaseActivity {  public static void start(Context context) {    Intent intent = new Intent();    intent.setClass(context, Typography4Activity.class);    context.startActivity(intent);  }  private LinearLayout root;  private Paint leftPaint = new Paint();  private float textSize;  private float maxLeftWidth;  private int middlePadding = 0;  private float maxRightWidth;  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    root = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.activity_typography4, null);    setContentView(root);    initPaint();    findViews();    loadData();  }  private void initPaint() {    textSize = getResources().getDimensionPixelSize(R.dimen.text_size_13);    leftPaint.setAntiAlias(true);    leftPaint.setTextSize(textSize);    leftPaint.setColor(getResources().getColor(R.color.color_black_999999));    middlePadding = getResources().getDimensionPixelSize(R.dimen.padding_value);  }  private void findViews() {  }  private void loadData() {    addGridLayout(DataSource.getArray());    TextView view = new TextView(this);    view.setText("修改后的實現");    view.setGravity(Gravity.CENTER);    view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 160));    root.addView(view);    addModifyGridLayout(DataSource.getArray());  }  private void addGridLayout(JSONArray data) {    try {      GridLayout layout = createGridLayout();      int size = data.length();      for (int i = 0; i < size; ++i) {        JSONArray item = (JSONArray) data.get(i);        String key = item.getString(0);        String value = (item.length() >= 2) ? item.getString(1) : "";        GridLayout.Spec row = GridLayout.spec(i);        GridLayout.Spec col1 = GridLayout.spec(0);        GridLayout.Spec col2 = GridLayout.spec(1);        GridLayout.LayoutParams params = new GridLayout.LayoutParams(row, col1);        TextView title = getLeftTextView(key);        layout.addView(title, params);        params = new GridLayout.LayoutParams(row, col2);        TextView desc = getRightTextView(value);        layout.addView(desc, params);      }      root.addView(layout);    } catch (Exception e) {    }  }  @NonNull  private TextView getRightTextView(String value) {    TextView desc = new TextView(this);    desc.setTextSize(13);    desc.setTextColor(getResources().getColor(R.color.black));    desc.setText(value);    return desc;  }  @NonNull  private TextView getLeftTextView(String key) {    TextView title = new TextView(this);    title.setText(key);    title.setPadding(0, middlePadding, middlePadding, 0);    title.setTextColor(getResources().getColor(R.color.color_black_999999));    title.setTextSize(13);    return title;  }  private void addModifyGridLayout(JSONArray data) {    try {      calculateLeftMaxWidth(data);      GridLayout layout = createGridLayout();      int size = data.length();      for (int i = 0; i < size; ++i) {        JSONArray item = (JSONArray) data.get(i);        GridLayout.Spec row = GridLayout.spec(i);        String key = item.getString(0);        GridLayout.Spec col1 = GridLayout.spec(0);        GridLayout.LayoutParams params = new GridLayout.LayoutParams(row, col1);        TextView title = getLeftTextView(key);        layout.addView(title, params);        String value = (item.length() >= 2) ? item.getString(1) : "";        GridLayout.Spec col2 = GridLayout.spec(1);        params = new GridLayout.LayoutParams(row, col2);        TextView desc = getRightTextView(value);        params.width = (int) maxRightWidth;        params.height = ViewGroup.LayoutParams.WRAP_CONTENT;        layout.addView(desc, params);      }      root.addView(layout);    } catch (Exception e) {    }  }  private void calculateLeftMaxWidth(JSONArray data) {    try {      DisplayUtil.init(this);// 這個可以在應用程序起來的時候init      int size = data.length();      for (int i = 0; i < size; ++i) {        JSONArray o = (JSONArray) data.get(i);        String key = o.getString(0);        String value = o.getString(1);        if (TextUtils.isEmpty(key) || TextUtils.isEmpty(value)) {          continue;        }        float curWidth = leftPaint.measureText(key);        if (curWidth > maxLeftWidth) {          maxLeftWidth = curWidth;        }      }      maxLeftWidth = maxLeftWidth + middlePadding;      maxRightWidth = DisplayUtil.screenWidth - DisplayUtil.dp2px(this, 32 + 10) - maxLeftWidth;    } catch (Exception e) {    }  }  private GridLayout createGridLayout() {    GridLayout layout = new GridLayout(this);    layout.setColumnCount(2);    //layout.setRowCount(5);    layout.setOrientation(GridLayout.HORIZONTAL);    return layout;  }}

       如果直接創建一個GridLayout,里面添加每一項,如果描述過長都導致顯示不全,這個是系統的一個bug,計算的寬度有問題,因此需要對此方案進行更改。
       更改方式為先計算左邊占用的最大寬度,在添加右邊的項時,設置布局參數控制最大的長度。

方案5

       采用每一行一個布局,手動一行一行進行添加:

public class Typography5Activity extends BaseActivity {  public static void start(Context context) {    Intent intent = new Intent();    intent.setClass(context, Typography5Activity.class);    context.startActivity(intent);  }  private LinearLayout root;  private Paint leftPaint = new Paint();  private float textSize;  private float maxLeftWidth;  private int middlePadding = 0;  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    root = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.activity_typography5, null);    setContentView(root);    initPaint();    loadData();  }  private void initPaint() {    textSize = getResources().getDimensionPixelSize(R.dimen.text_size_13);    leftPaint.setAntiAlias(true);    leftPaint.setTextSize(textSize);    leftPaint.setColor(getResources().getColor(R.color.color_black_999999));    middlePadding = getResources().getDimensionPixelSize(R.dimen.padding_value);  }  private void loadData() {    JSONArray array = DataSource.getArray();    calculateLeftMaxWidth(array);    if (array != null) {      try {        int size = array.length();        for (int i = 0; i < size; ++i) {          JSONArray o = (JSONArray) array.get(i);          String key = o.getString(0);          String value = o.getString(1);          addItem(key, value);        }      } catch (Exception e) {      }    }  }  private void calculateLeftMaxWidth(JSONArray data) {    try {      int size = data.length();      for (int i = 0; i < size; ++i) {        JSONArray o = (JSONArray) data.get(i);        String key = o.getString(0);        String value = o.getString(1);        if (TextUtils.isEmpty(key) || TextUtils.isEmpty(value)) {          continue;        }        float curWidth = leftPaint.measureText(key);        if (curWidth > maxLeftWidth) {          maxLeftWidth = curWidth;        }      }      maxLeftWidth = maxLeftWidth + middlePadding;    } catch (Exception e) {    }  }  private void addItem(String key, String value) {    LinearLayout layout = getItemLayout();    TextView left = (TextView) layout.findViewById(R.id.left);    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,        ViewGroup.LayoutParams.WRAP_CONTENT);    params.width = (int) maxLeftWidth;    left.setLayoutParams(params);    left.setText(key);    TextView right = (TextView) layout.findViewById(R.id.right);    right.setText(value);    root.addView(layout);  }  private LinearLayout getItemLayout() {    LinearLayout layout = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.compose_item_layout, null);    return layout;  }}

       改方案也需要先計算左邊的最大占用寬度,來設置右邊占用的大小,每一項的布局如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:orientation="horizontal"  android:paddingTop="@dimen/text_padding_10"  tools:context=".activity.Typography1Activity">  <TextView    android:id="@+id/left"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_marginRight="@dimen/text_padding_10"    android:textColor="@color/color_black_999999"    android:textSize="@dimen/text_size_13"/>  <TextView    android:id="@+id/right"    android:layout_width="0dp"    android:layout_height="wrap_content"    android:layout_weight="1"    android:textColor="@color/black"    android:textSize="@dimen/text_size_13"/></LinearLayout>

       每一行有兩個TextView,左邊寬度為自適應,右邊占據剩下左右的位置,在計算出左邊最大寬度后,重新設置左邊每一個TextView占用的寬度。

方案6

       方式與1差不多,但是不在繼承TextView,而是直接繼承View:

public class TypographyView4 extends View {  private Paint leftPaint = new Paint();  private Paint rightPaint = new Paint();  private int fullWidth;  private float textSize;  private JSONArray array;  private int middlePadding = 0;  float maxLeftWidth = 0;  int itemSize = 0;  public TypographyView4(Context context) {    super(context);    init();  }  public TypographyView4(Context context, AttributeSet attrs) {    super(context, attrs);    init();  }  public TypographyView4(Context context, AttributeSet attrs, int defStyleAttr) {    super(context, attrs, defStyleAttr);    init();  }  private void init() {    textSize = getResources().getDimensionPixelSize(R.dimen.text_size_13);    leftPaint.setAntiAlias(true);    leftPaint.setTextSize(textSize);    leftPaint.setColor(getResources().getColor(R.color.color_black_999999));    rightPaint.setAntiAlias(true);    rightPaint.setTextSize(textSize);    rightPaint.setColor(getResources().getColor(R.color.color_black));    middlePadding = getResources().getDimensionPixelSize(R.dimen.padding_value);  }  @Override  protected void onSizeChanged(int w, int h, int oldw, int oldh) {    super.onSizeChanged(w, h, oldw, oldh);    fullWidth = getWidth();// 整個textView的寬度  }  public void setText(JSONArray array) {    this.array = array;    if (array != null) {      try {        int size = itemSize = array.length();        for (int i = 0; i < size; ++i) {          JSONArray o = (JSONArray) array.get(i);          String key = o.getString(0);          String value = o.getString(1);          if (TextUtils.isEmpty(key) || TextUtils.isEmpty(value)) {            itemSize--;            continue;          }          float curWidth = leftPaint.measureText(key);          if (curWidth > maxLeftWidth) {            maxLeftWidth = curWidth;          }        }        maxLeftWidth = maxLeftWidth + middlePadding;        invalidate();      } catch (Exception e) {      }    }  }  @Override  protected void onDraw(Canvas canvas) {    if (array == null) {      return;    }    int lineCount = 0;    try {      JSONArray item;      float offsetY;      for (int i = 0; i < itemSize; ++i) {        item = (JSONArray) array.get(i);        offsetY = (lineCount + 1) * textSize;        canvas.drawText(item.getString(0), 0, offsetY, leftPaint);        String value = item.getString(1);        float valueWidth = rightPaint.measureText(value);        if (valueWidth > fullWidth - maxLeftWidth) {// 一行顯示不完          char[] textCharArray = value.toCharArray();          float charWidth;          float drawWidth = maxLeftWidth;          for (int j = 0; j < textCharArray.length; j++) {            charWidth = rightPaint.measureText(textCharArray, j, 1);            if (fullWidth - drawWidth < charWidth) {              lineCount++;              drawWidth = maxLeftWidth;              offsetY += textSize;            }            canvas.drawText(textCharArray, j, 1, drawWidth, offsetY, rightPaint);            drawWidth += charWidth;          }        } else {          canvas.drawText(value, maxLeftWidth, offsetY, rightPaint);        }        lineCount += 2;      }    } catch (JSONException e) {      e.printStackTrace();    }  }}

       該方案主要繼承自View,不再繼承TextView,由于在在上述方案中不在調用super,因此TextView已經退化為一個View,因此直接繼承View。

總結

       因為左邊的寬度不確定,因此所有的方案都進行了同樣的一個操作,就是測量了左邊顯示的最大寬度,后續的操作再根據該寬度進行調整。上述的方案中1,2,3,6都只需用一個View來進行顯示,4,5都需要多個View進行顯示。

 完整的代碼可以在查看鏈接上進行查看。

以上就是本文的全部內容,希望對大家的學習有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 泰和县| 友谊县| 张家港市| 福泉市| 金坛市| 上饶市| 云浮市| 台安县| 鄢陵县| 浪卡子县| 佳木斯市| 桑植县| 红安县| 民权县| 商洛市| 福泉市| 呼伦贝尔市| 天气| 金塔县| 响水县| 县级市| 平果县| 灌云县| 黄山市| 邢台市| 龙岩市| 清涧县| 城市| 柯坪县| 栾城县| 临漳县| 岗巴县| 富宁县| 高唐县| 高平市| 宁海县| 天门市| 凤凰县| 铜川市| 雷波县| 贵港市|