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

Android自定義View實現(xiàn)LayoutParams的方法詳解

 更新時間:2023年02月02日 10:36:36   作者:dora  
這篇文章主要為大家詳細(xì)介紹了Android自定義View實現(xiàn)LayoutParams,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

這一期我們來講一講LayoutParams這個玩意兒。Android入門的第一行代碼就牽扯到這個東西,然而,你真的理解夠了嗎?

第一層理解

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
</RelativeLayout>

layout_width和layout_height這個是不是最開始學(xué)的時候,就要搞清楚的基礎(chǔ)知識,match_parent代表填充屏幕,wrap_content代表包裹內(nèi)容。這些其實是系統(tǒng)控件定義的屬性,通過TypedArray進(jìn)行解析。

第二層理解

val lp = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
lp.addRule(RelativeLayout.CENTER_VERTICAL)
lp.addRule(RelativeLayout.BELOW, viewId)
lp.setMargins(10, 20, 10, 20)

使用代碼動態(tài)布局的時候設(shè)置LayoutParams。

第三層理解

好了,知識是在不斷打破舊的認(rèn)識中進(jìn)步的,第一層實際還沒到LayoutParams,還只是AttributeSet。系統(tǒng)何時將布局中的AttributeSet解析成LayoutParams的呢?

@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
    return new RelativeLayout.LayoutParams(getContext(), attrs);
}

protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}

ViewGroup有個關(guān)鍵的方法,generateLayoutParams()。

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

    TypedArray a = c.obtainStyledAttributes(attrs,
            com.android.internal.R.styleable.RelativeLayout_Layout);

    final int targetSdkVersion = c.getApplicationInfo().targetSdkVersion;
    mIsRtlCompatibilityMode = (targetSdkVersion < JELLY_BEAN_MR1 ||
            !c.getApplicationInfo().hasRtlSupport());

    final int[] rules = mRules;
    //noinspection MismatchedReadAndWriteOfArray
    final int[] initialRules = mInitialRules;

    final int N = a.getIndexCount();
    for (int i = 0; i < N; i++) {
        int attr = a.getIndex(i);
        switch (attr) {
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignWithParentIfMissing:
                alignWithParent = a.getBoolean(attr, false);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_toLeftOf:
                rules[LEFT_OF] = a.getResourceId(attr, 0);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_toRightOf:
                rules[RIGHT_OF] = a.getResourceId(attr, 0);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_above:
                rules[ABOVE] = a.getResourceId(attr, 0);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_below:
                rules[BELOW] = a.getResourceId(attr, 0);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignBaseline:
                rules[ALIGN_BASELINE] = a.getResourceId(attr, 0);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignLeft:
                rules[ALIGN_LEFT] = a.getResourceId(attr, 0);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignTop:
                rules[ALIGN_TOP] = a.getResourceId(attr, 0);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignRight:
                rules[ALIGN_RIGHT] = a.getResourceId(attr, 0);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignBottom:
                rules[ALIGN_BOTTOM] = a.getResourceId(attr, 0);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignParentLeft:
                rules[ALIGN_PARENT_LEFT] = a.getBoolean(attr, false) ? TRUE : 0;
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignParentTop:
                rules[ALIGN_PARENT_TOP] = a.getBoolean(attr, false) ? TRUE : 0;
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignParentRight:
                rules[ALIGN_PARENT_RIGHT] = a.getBoolean(attr, false) ? TRUE : 0;
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignParentBottom:
                rules[ALIGN_PARENT_BOTTOM] = a.getBoolean(attr, false) ? TRUE : 0;
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_centerInParent:
                rules[CENTER_IN_PARENT] = a.getBoolean(attr, false) ? TRUE : 0;
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_centerHorizontal:
                rules[CENTER_HORIZONTAL] = a.getBoolean(attr, false) ? TRUE : 0;
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_centerVertical:
                rules[CENTER_VERTICAL] = a.getBoolean(attr, false) ? TRUE : 0;
               break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_toStartOf:
                rules[START_OF] = a.getResourceId(attr, 0);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_toEndOf:
                rules[END_OF] = a.getResourceId(attr, 0);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignStart:
                rules[ALIGN_START] = a.getResourceId(attr, 0);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignEnd:
                rules[ALIGN_END] = a.getResourceId(attr, 0);
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignParentStart:
                rules[ALIGN_PARENT_START] = a.getBoolean(attr, false) ? TRUE : 0;
                break;
            case com.android.internal.R.styleable.RelativeLayout_Layout_layout_alignParentEnd:
                rules[ALIGN_PARENT_END] = a.getBoolean(attr, false) ? TRUE : 0;
                break;
        }
    }
    mRulesChanged = true;
    System.arraycopy(rules, LEFT_OF, initialRules, LEFT_OF, VERB_COUNT);

    a.recycle();
}

這個代碼熟悉吧,這就是我們之前講過的自定義屬性?。]錯,xml布局中的屬性會先被解析成LayoutParams。那么我問你個問題,你覺得generateLayoutParams()和generateDefaultLayoutParams()的這個LayoutParams是給自己用的呢?還是給它的子控件用的呢?它是給子控件用的。自己的那個直接在構(gòu)造方法中就從AttributeSet解析出來了。這樣你就理解了,為什么RelativeLayout的那些個

android:layout_centerVertical="true"
android:layout_alignParentEnd="true"

怎么全部定義在子控件里面了。然后ViewGroup的addView()方法中就可以帶上這個LayoutParams了。

/**
 * Adds a child view. If no layout parameters are already set on the child, the
 * default parameters for this ViewGroup are set on the child.
 *
 * <p><strong>Note:</strong> do not invoke this method from
 * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
 * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
 *
 * @param child the child view to add
 * @param index the position at which to add the child
 *
 * @see #generateDefaultLayoutParams()
 */
public void addView(View child, int index) {
    if (child == null) {
        throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
    }
    LayoutParams params = child.getLayoutParams();
    if (params == null) {
        params = generateDefaultLayoutParams();
        if (params == null) {
            throw new IllegalArgumentException(
                    "generateDefaultLayoutParams() cannot return null  ");
        }
    }
    addView(child, index, params);
}

你不重寫generateLayoutParams()方法,怎么在添加子控件的時候,讓子控件用你的LayoutParams呢?

public static class LayoutParams extends ViewGroup.MarginLayoutParams {
}

以上是LinearLayout.LayoutParams的摘要,我們自定義ViewGroup的時候,是不是也可以繼承個ViewGroup的LayoutParams玩一玩呢?然后重寫generateLayoutParams()和generateDefaultLayoutParams()方法。

@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
    return new LinearLayout.LayoutParams(getContext(), attrs);
}

這里return你的ViewGroup的LayoutParams,然后在你的ViewGroup的LayoutParams的構(gòu)造方法中就可以解析自定義屬性attrs了。如果忘記了解析方式,我給你個提示,使用context的obtainStyledAttributes()方法。

大部分停留在第二層理解,你如果學(xué)會了第三層,那么你自定義View又可以玩出新的高度了。

到此這篇關(guān)于Android自定義View實現(xiàn)LayoutParams的方法詳解的文章就介紹到這了,更多相關(guān)Android LayoutParams內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android NDK開發(fā)詳細(xì)介紹

    Android NDK開發(fā)詳細(xì)介紹

    本文主要介紹Android NDK開發(fā),這里詳細(xì)整理了相關(guān)資料并介紹 NDK的知識和開發(fā)流程及簡單示例代碼,幫助大家學(xué)習(xí),有需要的小伙伴可以參考下
    2016-09-09
  • Android 判斷程序在前臺運行還是后臺運行

    Android 判斷程序在前臺運行還是后臺運行

    本文主要介紹了Android 判斷程序在前臺運行還是后臺運行的方法。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-04-04
  • Android入門之Service的使用詳解

    Android入門之Service的使用詳解

    我們的Android在啟動一些長事務(wù)時都會使用異步,很多初學(xué)者覺得這個異步就是一個異步線程+Handler而己。如果你這么想就錯了。這一切其實靠的正是Android里的Service。本文就來和大家聊聊Service的生命周期和使用,需要的可以參考一下
    2022-12-12
  • WorkManager解決應(yīng)用退出后繼續(xù)運行后臺任務(wù)

    WorkManager解決應(yīng)用退出后繼續(xù)運行后臺任務(wù)

    這篇文章主要為大家介紹了WorkManager解決應(yīng)用退出后繼續(xù)運行后臺任務(wù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Android camera實時預(yù)覽 實時處理,人臉識別示例

    Android camera實時預(yù)覽 實時處理,人臉識別示例

    本篇文章主要介紹了Android camera實時預(yù)覽 實時處理,面部認(rèn)證示例,具有一定的參考價值,有興趣的可以了解一下。
    2017-01-01
  • 解決Android Studio xml 格式化不自動換行的問題

    解決Android Studio xml 格式化不自動換行的問題

    這篇文章主要介紹了解決Android Studio xml 格式化不自動換行的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Android編程實現(xiàn)切換imageView的方法分析

    Android編程實現(xiàn)切換imageView的方法分析

    這篇文章主要介紹了Android編程實現(xiàn)切換imageView的方法,結(jié)合具體實例形式分析了切換imageView的相關(guān)設(shè)置技巧與注意事項,需要的朋友可以參考下
    2017-09-09
  • Android實現(xiàn)系統(tǒng)打印功能

    Android實現(xiàn)系統(tǒng)打印功能

    這篇文章主要為大家詳細(xì)介紹了Android實現(xiàn)系統(tǒng)打印功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • Android 渲染機(jī)制深入理解

    Android 渲染機(jī)制深入理解

    這篇文章主要介紹了Android 渲染機(jī)制深入理解的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Android studio 禁用AndroidX方式

    Android studio 禁用AndroidX方式

    這篇文章主要介紹了Android studio 禁用AndroidX方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04

最新評論

西林县| 漯河市| 彰武县| 若羌县| 灵丘县| 老河口市| 巴里| 玉树县| 绩溪县| 舒兰市| 阿图什市| 沙河市| 杂多县| 株洲市| 孝昌县| 清徐县| 五寨县| 滕州市| 阿克| 喀喇| 东山县| 原阳县| 夏河县| 福清市| 鄂州市| 安福县| 溧阳市| 民和| 修文县| 麻城市| 西充县| 成都市| 宣汉县| 股票| 新宁县| 井冈山市| 沁阳市| 特克斯县| 仲巴县| 正安县| 大丰市|