カスタムviewgroupピット、サブviewのmarginを取得できません
4966 ワード
今日、カスタムviewを使用するときは、親レイアウトがmarginを担当し、サブレイアウトがpaddingを担当していることしか知られていませんでした.カスタムviewgroupを使用している間もmarginということは考えていませんでしたが、今日突然やってみたいと思い、
その理由の多くは、取得したlayoutParamsがMarginLayoutParamsではなく、ネット上のブログを見てみると、layoutParamsがMarginLayoutParamsに強く移行してアクティブなmarginになったことをデフォルトで取得していたため、デバッグしてみると、取得したのはMarginLayoutParamsではないことが分かったので、ごろつきはソースコードを見るしかありません.xmlはinflateで解析して対応するviewを生成していると思いますので、LayoutInflateのinflateメソッドを見てみましょう
xmlを解析してこのviewを取得するtryInflatePrecompiledメソッドが呼び出され、対応するlayoutParamsを生成するメソッドがviewに追加されていることがわかります.
このattachToRootパラメータもよく知られています.親レイアウトに追加するか、レイアウトパラメータのみを適用するかです.また、このgenerateLayoutParamsメソッドではデフォルトのlayoutParamsパラメータしか生成されませんので、カスタムviewgroupはこのメソッドを書き換える必要があります.そうしないとmarginは使用できません.
したがって,この方法を直接書き換えてMarginLayoutParamsに戻るのが一般的であり,MarginLayoutParamsクラスでは受信したattrsを解析してmarginを取得する過程も見られる.
またviewgroupでondrawを使用して必要なインタフェースを描画する場合は、初期化関数に
child.marginTop
で取得した0を発見しました.この時、これはkotlinの拡張方法です.以下のように見てみましょう.inline val View.marginTop: Int
get() = (layoutParams as? MarginLayoutParams)?.topMargin ?: 0
その理由の多くは、取得したlayoutParamsがMarginLayoutParamsではなく、ネット上のブログを見てみると、layoutParamsがMarginLayoutParamsに強く移行してアクティブなmarginになったことをデフォルトで取得していたため、デバッグしてみると、取得したのはMarginLayoutParamsではないことが分かったので、ごろつきはソースコードを見るしかありません.xmlはinflateで解析して対応するviewを生成していると思いますので、LayoutInflateのinflateメソッドを見てみましょう
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
View view = tryInflatePrecompiled(resource, res, root, attachToRoot);
if (view != null) {
return view;
}
}
xmlを解析してこのviewを取得するtryInflatePrecompiledメソッドが呼び出され、対応するlayoutParamsを生成するメソッドがviewに追加されていることがわかります.
ViewGroup.LayoutParams params = root.generateLayoutParams(attrs);
if (attachToRoot) {
root.addView(view, params);
} else {
view.setLayoutParams(params);
}
このattachToRootパラメータもよく知られています.親レイアウトに追加するか、レイアウトパラメータのみを適用するかです.また、このgenerateLayoutParamsメソッドではデフォルトのlayoutParamsパラメータしか生成されませんので、カスタムviewgroupはこのメソッドを書き換える必要があります.そうしないとmarginは使用できません.
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
したがって,この方法を直接書き換えてMarginLayoutParamsに戻るのが一般的であり,MarginLayoutParamsクラスでは受信したattrsを解析してmarginを取得する過程も見られる.
またviewgroupでondrawを使用して必要なインタフェースを描画する場合は、初期化関数に
setWillNotDraw(false)
を設定する必要があります.そうしないとonDrawメソッドは呼び出されません.