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

Android中使用自定義ViewGroup的總結

 更新時間:2017年01月14日 16:29:16   作者:CoolEgos  
本篇文章主要介紹了Android中使用自定義ViewGroup的總結,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

分類

自定義Layout可以分為兩種情況。

  • 自定義ViewGroup,創(chuàng)造出一些不同于LinearLayout,RelativeLayout等之類的ViewGroup。比如:API 14以后增加的GridLayout、design support library中的CoordinatorLayout等等。
  • 自定義一些已經(jīng)有的Layout然后加一些特殊的功能。比如:TableLayout以及percent support library中的PercentFrameLayout等等。

流程

自定義View的流程是:onMeasure()->onLayout()->onDraw()。自定義ViewGroup的時候一般是不要去實現(xiàn)onDraw的,當然也可能有特殊的需求,比如:CoordinatorLayout。

所以onMeasure和onLayout基本能做大部分我們接觸的ViewGroup。但是僅僅的知道在onMeasure中測量ViewGroup的大小以及在onLayout中計算Child View的位置還是不夠。

比如:怎么可以給ViewGroup的Child View設置屬性?

一個例子。

寫一個自定義的ViewGroup,增加一個屬性控制Child View的大小(長寬)占ViewGroup的比例。

假設是一個LinearLayout,那么就先定義一個CustomLinearLayout。

public class CustomLinearLayout extends LinearLayout {
  public CustomLinearLayout(Context context) {
    super(context);
  }

  public CustomLinearLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }

  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
  }
}

其它拋開不說,我們是需要增加屬性用來控制Child View的大小。那么就先在value/attr.xml中定義那個屬性(使用CustomLinearLayout_Layout來與CustomLinearLayout區(qū)分下,當然這個名字是隨意的)。

<declare-styleable name="CustomLinearLayout_Layout">
  <!-- 定義比例 -->
  <attr name="inner_percent" format="float"/>
</declare-styleable>

ViewGroup調用addView()的時候最終都會調用到這個方法。

public void addView(View child, int index, LayoutParams params)

這個params代表的就是View的配置,ViewGroup.LayoutParams中就包含了width、height,LinearLayout.LayoutParams增加了weight屬性等等。那么我們就應該實現(xiàn)一個LayoutParams。那么現(xiàn)在就是這樣了。

public class CustomLinearLayout extends LinearLayout {
  public CustomLinearLayout(Context context) {
    super(context);
  }

  public CustomLinearLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }

  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
  }
  public static class LayoutParams extends LinearLayout.LayoutParams {

    private float innerPercent;

    private static final int DEFAULT_WIDTH = WRAP_CONTENT;
    private static final int DEFAULT_HEIGHT = WRAP_CONTENT;

    public LayoutParams() {
      super(DEFAULT_WIDTH, DEFAULT_HEIGHT);
      innerPercent = -1.0f;
    }

    public LayoutParams(float innerPercent) {
      super(DEFAULT_WIDTH, DEFAULT_HEIGHT);
      this.innerPercent = innerPercent;
    }

    public LayoutParams(ViewGroup.LayoutParams p) {
      super(p);
    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    public LayoutParams(LinearLayout.LayoutParams source) {
      super(source);
    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    public LayoutParams(LayoutParams source) {
      super(source);
      this.innerPercent = source.innerPercent;
    }

    public LayoutParams(Context c, AttributeSet attrs) {
      super(c, attrs);
      init(c, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
      TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomLinearLayout_Layout);
      innerPercent = a.getFloat(R.styleable.CustomLinearLayout_Layout_inner_percent, -1.0f);
      a.recycle();
    }
  }
}

現(xiàn)在就可以在xml使用我們的屬性了。

<?xml version="1.0" encoding="utf-8"?>
<com.egos.samples.custom_layout.CustomLinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="200dp"
  android:layout_height="200dp"
  android:id="@+id/test_layout"
  android:background="#ffff0000"
  android:gravity="center"
  android:orientation="vertical">
  <ImageView
    android:text="Egos"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:onClick="add"
    android:background="#ff00ff00"
    app:inner_percent="0.8"/>
</com.egos.samples.custom_layout.CustomLinearLayout>

只是然并軟,并沒有作用。

那么到底是怎么去控制Child View的大小呢?當然是在onMeasure控制的。addView會執(zhí)行下面的代碼。

requestLayout();
invalidate(true);

這樣的話就會重新的走一遍onMeasure(),onLayout()了。實現(xiàn)onMeasure()的方法以后直接去處理Child View的大小,因為我繼承的是LinearLayout,所以其實是會處理到measureChildBeforeLayout()。最終是在measureChildBeforeLayout的時候來處理Child View的大小。

@Override 
protected void measureChildWithMargins(View child, int parentWidthMeasureSpec,
                    int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
  // 在xml強制寫成match_parent,然后在這里強制設置成
  if (child != null && child.getLayoutParams() instanceof LayoutParams &&
      ((LayoutParams) child.getLayoutParams()).innerPercent != -1.0f) {
    parentWidthMeasureSpec = MeasureSpec.makeMeasureSpec((int) (MeasureSpec.getSize(parentWidthMeasureSpec) *
        ((LayoutParams) child.getLayoutParams()).innerPercent), MeasureSpec.getMode(parentWidthMeasureSpec));
    parentHeightMeasureSpec = MeasureSpec.makeMeasureSpec((int) (MeasureSpec.getSize(parentHeightMeasureSpec) *
        ((LayoutParams) child.getLayoutParams()).innerPercent), MeasureSpec.getMode(parentHeightMeasureSpec));
    super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed,
      parentHeightMeasureSpec, heightUsed);
  } else {
    super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed,
        parentHeightMeasureSpec, heightUsed);
  }
}

這樣就可以實現(xiàn)最開始的需求了。

其實還有一些細節(jié)是需要處理的,下面的代碼就是。

/**
 * 當checkLayoutParams返回false的時候就會執(zhí)行到這里的generateLayoutParams
 */
 @Override
protected LinearLayout.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
  return super.generateLayoutParams(lp);
}

/**
 * 當addView的時候沒有設置LayoutParams的話就會默認執(zhí)行這里的generateDefaultLayoutParams
 */
@Override
protected LayoutParams generateDefaultLayoutParams() {
  return new LayoutParams();
}

/**
 * 寫在xml中屬性的時候就會執(zhí)行這里的generateLayoutParams
 */
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
  return new LayoutParams(getContext(), attrs);
}

總結一下

  • 自定義View和ViewGroup需要多多注意的都是onMeasure、onLayout、onDraw。
  • 把ViewGroup自身的屬性和Child View的屬性區(qū)分開。
  • 可以多多的參考support包中的代碼,調試也非常的方便。

做Android開發(fā),自身需要自定義View的地方確實是比較的多,只是大部分都會有相應的開源庫。但是我們還是應該需要熟練的知道該如何自定義一個ViewGroup。

自己是一個比較健忘的人,所以寫的詳細點。

完整的代碼戳這里。

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

相關文章

  • android?原生安全音量配置邏輯設計詳解

    android?原生安全音量配置邏輯設計詳解

    這篇文章主要為大家介紹了android?原生安全音量配置邏輯設計詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • Android實現(xiàn)水波紋效果

    Android實現(xiàn)水波紋效果

    這篇文章主要介紹了Android實現(xiàn)水波紋效果的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-10-10
  • Android Force Close 出現(xiàn)的異常原因分析及解決方法

    Android Force Close 出現(xiàn)的異常原因分析及解決方法

    本文給大家講解Android Force Close 出現(xiàn)的異常原因分析及解決方法,forceclose意為強行關閉,當前應用程序發(fā)生了沖突。對android force close異常分析感興趣的朋友一起通過本文學習吧
    2016-08-08
  • Android APK應用安裝原理解析之AndroidManifest使用PackageParser.parserPackage原理分析

    Android APK應用安裝原理解析之AndroidManifest使用PackageParser.parserPac

    這篇文章主要介紹了Android APK應用安裝原理解析之AndroidManifest使用PackageParser.parserPackage原理,結合實例形式分析了PackageManagerService調用PackageParser.parserPackage方法解析APK清單相關原理與操作技巧,需要的朋友可以參考下
    2017-12-12
  • Android 仿蘋果底部彈出Dialog

    Android 仿蘋果底部彈出Dialog

    這篇文章主要介紹了Android 仿蘋果底部彈出Dialog的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-12-12
  • Android實現(xiàn)背景顏色滑動漸變效果的全過程

    Android實現(xiàn)背景顏色滑動漸變效果的全過程

    在Android開發(fā)中,經(jīng)常需要設置控件的背景顏色或者圖片的src顏色,下面這篇文章主要給大家介紹了關于Android實現(xiàn)背景顏色滑動漸變效果的相關資料,本文通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-09-09
  • Android自定義控件實現(xiàn)手勢密碼

    Android自定義控件實現(xiàn)手勢密碼

    這篇文章主要介紹了Android自定義控件實現(xiàn)手勢密碼的相關資料,實現(xiàn)手勢解鎖功能,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Android 網(wǎng)絡圖片查看器與網(wǎng)頁源碼查看器

    Android 網(wǎng)絡圖片查看器與網(wǎng)頁源碼查看器

    本篇文章主要介紹了Android 網(wǎng)絡圖片查看器與網(wǎng)頁源碼查看器的相關知識。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-04-04
  • Android Studio中主題樣式的使用方法詳解

    Android Studio中主題樣式的使用方法詳解

    這篇文章主要介紹了Android Studio中主題樣式的使用方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • Android仿微信長按錄制視頻并播放功能

    Android仿微信長按錄制視頻并播放功能

    這篇文章主要為大家詳細介紹了Android仿微信長按錄制視頻并播放功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05

最新評論

青田县| 唐河县| 贺州市| 福泉市| 仪征市| 长武县| 博湖县| 绩溪县| 嘉荫县| 施甸县| 襄垣县| 德兴市| 临武县| 临武县| 卢龙县| 平武县| 沂源县| 贵溪市| 东台市| 镇安县| 景洪市| 普安县| 阳江市| 邹城市| 竹溪县| 德州市| 会宁县| 乌审旗| 曲阳县| 浠水县| 青州市| 大化| 德格县| 成都市| 高雄县| 休宁县| 塔河县| 楚雄市| 岱山县| 林芝县| 兴业县|