JavaSwing基礎のLayoutレイアウトに関する知識詳細
一、View layout方法
まず、
すみません、DecorViewにはlayout方法がありません。
ですから、直接にViewのは、まず、方法は、それぞれviewの は、次いで、 具体的な判断過程は古い上下左右の値と新しい上下左右の値を比較することであり、論理は
この
ですから、
そして、これらの値に基づいて、Viewの幅のような一連のパラメータを取得することができます。
次に
二、View Group layout方法
具体的な配置ロジックは、
次に、
三、カスタム垂直レイアウトVetical Layout
まず、私達はこのカスタム
View Groupを継承する
まず、このレイアウトは必ず
また、View Groupをカスタマイズするには、Generate LayoutParaamsが必要です。このステップは、私たちのView GroupがMarginをサポートするために、その後にMargine LayoutParaamsを通じてサブViewのMargin値を取得することができます。
その後、私たちは私たちのレイアウトを測定する必要があります。つまり、書き換え
この方法では、私たちのレイアウトを測定し、測定した幅の高さを
親Viewは、現在のビューの測定モードがMeass reSpec.EXACT LY であるとき。
つまり、幅が広い場合や高い場合は、現在のレイアウトViewの幅、つまり親Viewに設定して、測定サイズを設定してください。例えば、幅が測定モードがMeass reSpec.AT_である場合MOSTまたはUNSPECIFIED: この場合、親Viewの現在のビューに対する要求が固定されていないことを説明し、この
これで最終View Groupの高さ=すべてのサブビューの(高+margin値) 最終的なView Groupの幅=最大の子供Viewの(幅+margin値) 最後の呼び出し
レイアウトの方法を書き換えるonLayout
上記で述べたように、
垂直線形配置
それとも、位置、つまり
各Viewの 最後にサブビューのlayoutメソッドを呼び出して、各サブビューをレイアウトします。
成功しました。最後に私達のこの垂直直線レイアウトをカスタマイズした効果を見てみましょう。
四、効果展示
ここで、Javaの基礎となるLayoutレイアウトに関する詳細な文章を紹介します。Java Layoutレイアウトの内容については、以前の文章を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。
まず、
ViewRootImpl
から説明するか、インターフェースの描画はperformMeasure、performLayout
方法をトリガし、performLayout
方法でmViewのlayout
方法を呼び出して、複数のビューのレイアウト作業を開始する。
private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
int desiredWindowHeight) {
final View host = mView;
host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
}
mView
は全部分かりました。最上階のView――DecorView
です。DecorView
のラyout方法を見に行きます。すみません、DecorViewにはlayout方法がありません。
ですから、直接にViewの
layout
方法を見てみます。
public void layout(int l, int t, int r, int b) {
boolean changed = isLayoutModeOptical(mParent) ?
setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);
if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
onLayout(changed, l, t, r, b);
}
}
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
}
、 、 、
の4つの値を表す4つのパラメータを導入する。setOpticalFrame
方法またはsetFrame
方法によって、レイアウトパラメータが変更されたかどうかを判断する。setFrame
方法である。
protected boolean setFrame(int left, int top, int right, int bottom) {
boolean changed = false;
if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
changed = true;
// Remember our drawn bit
int drawn = mPrivateFlags & PFLAG_DRAWN;
int oldWidth = mRight - mLeft;
int oldHeight = mBottom - mTop;
int newWidth = right - left;
int newHeight = bottom - top;
boolean sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight);
// Invalidate our old position
invalidate(sizeChanged);
mLeft = left;
mTop = top;
mRight = right;
mBottom = bottom;
mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
}
return changed;
}
上下左右にパラメータ値が変化したら、このViewのレイアウトが変更されたと説明し、Viewの幅の高さ(newWidth、newHeight)を再計算し、Viewの新たな上下左右のパラメータ値を割り当てた。この
layout
の方法では主に4つのパラメータに関連しています。mLeft、mTop、mBottom、mRight
はそれぞれViewの左座標、上座標、下座標、右座標を表しています。Viewを長方形として理解して、この4つの値を決定して、Viewの長方形の4つの頂点値を決定できます。ですから、
layout
方法は一体何をしましたか?
に入力され、
に割り当てられ、終了することです。そして、これらの値に基づいて、Viewの幅のような一連のパラメータを取得することができます。
public final int getWidth() {
return mRight - mLeft;
}
これで、Viewのlayout
方法は終了し、主に上下左右のパラメータの割当値によってViewのレイアウトが完了し、非常に簡単である。次に
ViewGroup
を見ます。二、View Group layout方法
@Override
public final void layout(int l, int t, int r, int b) {
if (!mSuppressLayout && (mTransition == null || !mTransition.isChangingLayout())) {
if (mTransition != null) {
mTransition.layoutChange(this);
}
super.layout(l, t, r, b);
} else {
mLayoutCalledWhileSuppressed = true;
}
}
layout
とViewGroup
の配置過程は同じで、自分の位置を確定しましたか?View
の子供Viewはどうすればいいですか?大丈夫です。先ほどViewGroup
の方法を話した時に、layout
の方法が漏れました。でも、この方法はonLayout
の中で空いています。View
の中で抽象的な方法になりました。
@Override
protected abstract void onLayout(boolean changed,
int l, int t, int r, int b);
つまり、ViewGroup
の任意の方法は、ViewGroup
のレイアウト配置を完了するために実装されなければならない。具体的な配置ロジックは、
View
方式でonLayout
のlayoutメソッドを呼び出し、各サブビューのレイアウトを完成させ、最終的に描画作業を完了することである。次に、
View
を自分で実現して、次のセクションの ( LinearLayout)
とこのセクションのonMearsure
を復習します。三、カスタム垂直レイアウトVetical Layout
まず、私達はこのカスタム
onLayout
の役割を決定したいです。これは垂直方向のViewGroup
と同様の機能です。このView Groupの下のLinearLayout
は、垂直ライン順に順次下に排出してもいいです。私たちは View
という名前をつけました。View Groupを継承する
まず、このレイアウトは必ず
VerticalLayout
から継承され、対応する構成方法を実現する。
public class VerticalLayout : ViewGroup {
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int = 0) : super(
context,
attrs,
defStyleAttr
)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
}
}
generate LayoutParaamsを書き換える方法また、View Groupをカスタマイズするには、Generate LayoutParaamsが必要です。このステップは、私たちのView GroupがMarginをサポートするために、その後にMargine LayoutParaamsを通じてサブViewのMargin値を取得することができます。
override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams? {
return MarginLayoutParams(context, attrs)
}
測定方法を書き換えるその後、私たちは私たちのレイアウトを測定する必要があります。つまり、書き換え
ViewGroup
方法です。この方法では、私たちのレイアウトを測定し、測定した幅の高さを
onMeasure
方法に導入し、測定を完了する必要がある。
protected final void setMeasuredDimension(int measuredWidth, int measuredHeight)
前に述べたように、setMeasuredDimension
方法は2つのパラメータ、onMeasure
およびwidthMeasureSpec
に伝達される。親Viewは、現在のビューの
heightMeasureSpec
と親ViewのLayoutParams
に基づいて計算され、現在のビューに対して期待される
を含む。つまり、幅が広い場合や高い場合は、現在のレイアウトViewの幅、つまり親Viewに設定して、測定サイズを設定してください。例えば、幅が
であるなら、この固定値に直接呼び出し400dp
を再測定する必要はない。setMeasuredDimension
の高さを設定するとVerticalLayout
の大きさが任意であるか、または最大値を超えない場合である。この適応高さはどのように計算するべきかを設計者だけが知っているので、改めて高度測定をしなければなりません。具体的にはwrap_content
は垂直な直線配置であり、高さは自然とすべてのサブビューの高さの和である。これで
VerticalLayout
方法の論理もほぼ分かりました。
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
//
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
val sizeWidth = MeasureSpec.getSize(widthMeasureSpec)
val sizeHeight = MeasureSpec.getSize(heightMeasureSpec)
var mHeight = 0
var mWidth = 0
// View,
for (i in 0 until childCount) {
val childView = getChildAt(i)
// View
measureChild(childView, widthMeasureSpec, heightMeasureSpec)
val lp = childView.layoutParams as MarginLayoutParams
val childWidth = childView.measuredWidth + lp.leftMargin + lp.rightMargin
val childHeight = childView.measuredHeight + lp.topMargin + lp.bottomMargin
//
mWidth = Math.max(mWidth, childWidth)
//
mHeight += childHeight
}
//
setMeasuredDimension(
if (widthMode == MeasureSpec.EXACTLY) sizeWidth else mWidth,
if (heightMode == MeasureSpec.EXACTLY) sizeHeight else mHeight
)
}
主なロジックはViewを遍歴し、onMeasure
の実際の幅の高さを導出することである。VerticalLayout
測定モードにより、幅の高さが伝わります。レイアウトの方法を書き換えるonLayout
上記で述べたように、
setMeasuredDimension
として、子供Viewの通常のレイアウト配置を保証するために、ViewGroup
方法を書き換えなければならない。垂直線形配置
onLayout
もまたそうであるが、このレイアウトにおいてVerticalLayout
方法のキー論理は何であるか?それとも、位置、つまり
onLayout
の4つのパラメータ値を決定し、 、 、 、
において最も重要なパラメータはこれである。各Viewの
VerticalLayout
値は前のViewのbottom値でなければなりません。つまり前のViewに続いて並べられます。これがtop
の効果です。ですから、各Viewのtop
値を動的に計算する必要があります。つまり、次のビューのtop値として、Viewの高さを積み重ねていくのです。
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
var childWidth = 0
var childHeight = 0
var childTop = 0
var lp: MarginLayoutParams
// View, View
for (i in 0 until childCount) {
val childView = getChildAt(i)
childHeight = childView.measuredHeight
childWidth = childView.measuredWidth
lp = childView.layoutParams as MarginLayoutParams
// top
childTop += lp.topMargin
// View
childView.layout(
lp.leftMargin,
childTop,
lp.leftMargin + childWidth,
childTop + childHeight
);
childTop += childHeight + lp.bottomMargin
}
}
ロジックは簡単です。
は固定のサブビューのleftMaginである。top
は、アキュムレータ計算のサブビューの高さ+Margin値である。left
は、left+サブビューの幅である。top
はtop+サブビューの高さです。成功しました。最後に私達のこの垂直直線レイアウトをカスタマイズした効果を見てみましょう。
四、効果展示
<com.panda.studynote3.VerticalLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:text=" "
android:textSize="20sp"
android:textColor="@color/white"
android:background="@color/design_default_color_primary"
/>
<TextView
android:layout_width="300dp"
android:layout_height="200dp"
android:layout_marginTop="20dp"
android:background="@color/cardview_dark_background"
android:textSize="20sp"
android:textColor="@color/white"
android:text=" "
/>
<TextView
android:layout_width="140dp"
android:layout_height="100dp"
android:text=" "
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:textSize="20sp"
android:gravity="center"
android:textColor="@color/black"
android:background="@color/teal_200"
/>
</com.panda.studynote3.VerticalLayout>
ここで、Javaの基礎となるLayoutレイアウトに関する詳細な文章を紹介します。Java Layoutレイアウトの内容については、以前の文章を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。