最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android開發(fā)之天氣趨勢(shì)折線圖

 更新時(shí)間:2016年08月05日 11:14:44   投稿:daisy  
在開發(fā)天氣APP的時(shí)候會(huì)要顯示多天的信息,所以加一個(gè)折線圖來顯示一下天氣變化趨勢(shì)是很不錯(cuò)的效果,本文詳細(xì)介紹了開發(fā)過程,下面一起來看看。

先來看下效果:

控件內(nèi)容比較簡(jiǎn)單,就是一個(gè)普通的折線圖,上下分別帶有數(shù)字,點(diǎn)擊的時(shí)候顯示當(dāng)天溫度的差值。 

創(chuàng)建一個(gè)類繼承自View,并添加兩個(gè)構(gòu)造方法:

public class TrendGraph extends View {
  public TrendGraph(Context context) { // 在java代碼中創(chuàng)建調(diào)用
    super(context);
  }

  public TrendGraph(Context context, AttributeSet attrs) { // 在xml中創(chuàng)建調(diào)用
    super(context, attrs);
  }
} 

因?yàn)檫@里不需要考慮wrap_content的情況,所以onMeasure方法不需重寫,關(guān)鍵的是onDraw,而onDraw方法其實(shí)也不困難,只需要確定好每個(gè)點(diǎn)的具體位置就好,因?yàn)檫B線也是需要點(diǎn)的坐標(biāo),代碼比較啰嗦,可以略過:

   @Override
   protected void onDraw(Canvas canvas) {
     super.onDraw(canvas);
     if (mElements == null || mElements.size() == 0) {
       return;
     }
     double max_up = getMaxUp();
     double min_down = getMinDown();
     canvas.setDrawFilter(mDrawFilter);
     mPaint.setStrokeWidth(lineWeith);
     float width = getWidth();
     float grap = width / mElements.size();
     float textSize = mTextPaint.getTextSize();
     int textMargin = circleRadius * 2;
     float margin_top = textSize + 2 * textMargin;
     Log.d(TAG, "onDraw: " + margin_top + "|" + textSize);
     float height = getHeight() - 2 * margin_top;
 
     for (int i = 0; i < mElements.size() - 1; i++) {
       float startX = i * grap + grap / 2;
       float stopX = (i + 1) * grap + grap / 2;
       float startY = (float) (max_up - mElements.get(i).getUp()) / (float) (max_up -
           min_down) * height + margin_top;
       float stopY = (float) (max_up - mElements.get(i + 1).getUp()) / (float) (max_up -
           min_down) * height + margin_top;
 
       canvas.drawText((int) mElements.get(i).getUp() + "℃", startX - textSize, startY -
           textMargin, mTextPaint);
       canvas.drawCircle(startX, startY, circleRadius, mPaint);
       canvas.drawLine(startX, startY, stopX, stopY, mPaint);
       if (i == mElements.size() - 2) {
         canvas.drawText((int) mElements.get(i + 1).getUp() + "℃", stopX - textSize, stopY
             - textMargin, mTextPaint);
         canvas.drawCircle(stopX, stopY, circleRadius, mPaint);
       }
 
       startY = (float) (max_up - mElements.get(i).getDown()) / (float) (max_up - min_down) *
           height + margin_top;
       stopY = (float) (max_up - mElements.get(i + 1).getDown()) / (float) (max_up -
           min_down) * height + margin_top;
       canvas.drawText((int) mElements.get(i).getDown() + "℃", startX - textSize, startY +
           textSize + textMargin, mTextPaint);
       canvas.drawCircle(startX, startY, circleRadius, mPaint);
       canvas.drawLine(startX, startY, stopX, stopY, mPaint);
       if (i == mElements.size() - 2) {
         canvas.drawText((int) mElements.get(i + 1).getDown() + "℃", stopX - textSize,
             stopY + textSize + textMargin, mTextPaint);
         canvas.drawCircle(stopX, stopY, circleRadius, mPaint);
       }
     }
   }

考慮到需要允許用戶進(jìn)行簡(jiǎn)單的設(shè)置,例如點(diǎn)的大小,文字大小等等,所以定義一些自定義屬性(res/values/attr.xml):

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="TrendGraph">
    <attr name="lineWidth" format="dimension"/>
    <attr name="circleRadius" format="dimension" />
    <attr name="textSize" format="dimension" />
    <attr name="textColor" format="reference" />
  </declare-styleable>
</resources>

format指該屬性的格式,指定為dimension則是尺寸,取值單位是dp、sp或px等等,而reference則是引用,即一般在xml中引用其他資源的寫法,如@string/app_name。還有其他類型,可以自行查找文檔。 

對(duì)自定義屬性進(jìn)行解析得到,這個(gè)解析需要在上面定義的第二個(gè)構(gòu)造方法中進(jìn)行,代碼如下:

  public TrendGraph(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.TrendGraph);
    circleRadius = array.getDimensionPixelSize(R.styleable.TrendGraph_circleRadius, 5);
    lineWeith = array.getDimensionPixelSize(R.styleable.TrendGraph_lineWidth, 3);
    mTextPaint.setTextSize(array.getDimensionPixelSize(R.styleable.TrendGraph_textSize, 35));
    mTextPaint.setColor(array.getColor(R.styleable.TrendGraph_textColor, Color.BLACK));
    array.recycle();
  }

getDimensionPixelSize方法則是通過傳入的值,轉(zhuǎn)換為具體的像素(px)值,也就免去我們手動(dòng)轉(zhuǎn)換的麻煩。但是要注意,其中的defaultValue依然是px。

接著,就可以通過xml指定這些屬性,在布局中加入命名空間:

Android Studio會(huì)自動(dòng)引入,并且可以補(bǔ)全得到,具體使用:

  <com.fndroid.byweather.views.TrendGraph
    android:id="@+id/tg"
    android:layout_width="match_parent"
    app:textColor="@color/colorAccent"
    app:textSize="22sp"
    app:circleRadius="2dp"
    android:layout_height="200dp"/>

最后,添加一個(gè)事件監(jiān)聽,在點(diǎn)擊View的時(shí)候進(jìn)行回調(diào):

① 定義接口:

  public interface onItemClickListener{
    void onItemClick(View view, Element element);
  }

② 在View中添加接口對(duì)象,并設(shè)置setter方法:

public class TrendGraph extends View {

  private onItemClickListener mOnItemClickListener;

  // 省略代碼

  public void setOnItemClickListener(onItemClickListener onItemClickListener) {
    mOnItemClickListener = onItemClickListener;
  }

} 

③ 處理onTouchEvent,重寫該方法,代碼如下:

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    int viewWidth = getWidth();
    int itemWidth = viewWidth / mElements.size();
    int viewHeight = getHeight();
    boolean isMove = false; // 界面中最外層為一個(gè)NestedScrollView,所以為了避免滑動(dòng)時(shí)也觸發(fā),加入變量處理

    switch (event.getAction()) {
      case MotionEvent.ACTION_MOVE:
        isMove = true;
        break;
      case MotionEvent.ACTION_UP:
        if (!isMove){ // 判斷只有點(diǎn)擊時(shí)進(jìn)行回調(diào)
          int position = (int) (event.getX() / itemWidth); // 取得點(diǎn)擊的位置
          mOnItemClickListener.onItemClick(this, mElements.get(position)); // 回調(diào)
        }
        break;
    }

    return true;
  }

④ 在Activity中,進(jìn)行監(jiān)聽設(shè)置,并處理:

  historyGraph.setOnItemClickListener(this);
  @Override
  public void onItemClick(View view, TrendGraph.Element element) {
    int dt = (int) (element.getUp() - element.getDown());
    Snackbar.make(root, "當(dāng)天溫差為:" + dt + "℃", Snackbar.LENGTH_SHORT).show();
  }

總結(jié)

效果完成!如果有疑問歡迎大家交流討論,希望本文對(duì)大家開發(fā)Android能有所幫助。

相關(guān)文章

  • Android控制閃光燈的方法(打開與關(guān)閉)

    Android控制閃光燈的方法(打開與關(guān)閉)

    這篇文章主要介紹了Android控制閃光燈的方法,可實(shí)現(xiàn)閃光燈打開與關(guān)閉的效果,涉及Android操作Camera拍照閃光燈的相關(guān)技巧,需要的朋友可以參考下
    2016-01-01
  • Android開發(fā)之ViewSwitcher用法實(shí)例

    Android開發(fā)之ViewSwitcher用法實(shí)例

    這篇文章主要介紹了Android開發(fā)之ViewSwitcher用法,結(jié)合實(shí)例形式分析了ViewSwitcher的功能、使用方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2016-02-02
  • Android 超詳細(xì)講解fitsSystemWindows屬性的使用

    Android 超詳細(xì)講解fitsSystemWindows屬性的使用

    fitsSystemWindows屬性可以讓view根據(jù)系統(tǒng)窗口來調(diào)整自己的布局;簡(jiǎn)單點(diǎn)說就是我們?cè)谠O(shè)置應(yīng)用布局時(shí)是否考慮系統(tǒng)窗口布局,這里系統(tǒng)窗口包括系統(tǒng)狀態(tài)欄、導(dǎo)航欄、輸入法等,包括一些手機(jī)系統(tǒng)帶有的底部虛擬按鍵
    2022-03-03
  • Android中EditText+Button組合導(dǎo)致輸入板無法收起的原因分析及解決辦法

    Android中EditText+Button組合導(dǎo)致輸入板無法收起的原因分析及解決辦法

    這篇文章主要介紹了Android中EditText+Button組合導(dǎo)致輸入板無法收起的原因分析及解決辦法的相關(guān)資料,需要的朋友可以參考下
    2016-01-01
  • android仿微信通訊錄搜索示例(匹配拼音,字母,索引位置)

    android仿微信通訊錄搜索示例(匹配拼音,字母,索引位置)

    本篇文章主要介紹了android仿微信通訊錄搜索示例(匹配拼音,字母,索引位置),具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-09-09
  • Android微信簽名知識(shí)的總結(jié)

    Android微信簽名知識(shí)的總結(jié)

    這篇文章給大家詳細(xì)總結(jié)了Android微信簽名用到的知識(shí),文中通過具體的實(shí)現(xiàn)過程給大家進(jìn)行演示,相信對(duì)大家的理解很有幫助,下面來一起看看吧。
    2016-09-09
  • Android shape標(biāo)簽使用方法介紹

    Android shape標(biāo)簽使用方法介紹

    shape算是我們常用的一個(gè)標(biāo)簽,他可以生成線條,矩形, 圓形, 圓環(huán),像我們圓角的按鈕就可以通過shape來實(shí)現(xiàn),最終Android會(huì)把這個(gè)帶有shape標(biāo)簽的圖片解析成一個(gè)Drawable對(duì)象,這個(gè)Drawable對(duì)象本質(zhì)是GradientDrawable
    2022-09-09
  • 基于Android平臺(tái)實(shí)現(xiàn)拼圖小游戲

    基于Android平臺(tái)實(shí)現(xiàn)拼圖小游戲

    這篇文章主要為大家詳細(xì)介紹了基于Android平臺(tái)實(shí)現(xiàn)拼圖小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • flutter PageView實(shí)現(xiàn)左右滑動(dòng)切換視圖

    flutter PageView實(shí)現(xiàn)左右滑動(dòng)切換視圖

    這篇文章主要為大家詳細(xì)介紹了flutter PageView實(shí)現(xiàn)左右滑動(dòng)切換視圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • 超過百萬的StackOverflow Flutter 20大問題(推薦)

    超過百萬的StackOverflow Flutter 20大問題(推薦)

    這篇文章主要介紹了超過百萬的StackOverflow Flutter 問題,有的問題在stackoverflow上有幾十萬的閱讀量,說明很多人都遇到了這些問題,把這些問題整理分享給大家需要的朋友可以參考下
    2020-04-04

最新評(píng)論

安西县| 弋阳县| 虹口区| 奈曼旗| 南漳县| 安西县| 香港| 青田县| 隆林| 东乡县| 定远县| 天水市| 乌拉特中旗| 沅江市| 班玛县| 金平| 泰兴市| 仪陇县| 博罗县| 陆川县| 徐闻县| 锡林浩特市| 南靖县| 都昌县| 新乡县| 湖北省| 铜梁县| 龙州县| 五常市| 周至县| 华阴市| 宝坻区| 巴塘县| 商丘市| 清徐县| 聂荣县| 湛江市| 上杭县| 阿克陶县| 德令哈市| 宁津县|