更改视图的边距以编程方式。

huangapple go评论136阅读模式
英文:

Change a view margins programmatically

问题

我有一个RecyclerView,底部有250dp的边距,我需要以编程方式将底部边距设置为0dp,然后再将其设置回250dp。我尝试过这样做,但只能将其设置为0dp,设置为250dp无效:

ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) linearLayoutRv.getLayoutParams();
params.setMargins(0, 0, 0, 250); // 最初是 params.setMargins(0, 0, 0, 0);
linearLayoutRv.setLayoutParams(params);

这里有一些不必要的内容,但以下是XML文件:

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/linearLayoutRv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="250dp"
        android:gravity="center"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="51dp"
            android:gravity="center">
            <!-- 这里是TextView -->
        </androidx.constraintlayout.widget.ConstraintLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="51dp"
            android:orientation="horizontal">
            <!-- 这里是一些按钮 -->
        </LinearLayout>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginHorizontal="5dp"
            android:padding="4dp"
            android:scrollbars="vertical" />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
英文:

So I have a RecyclerView that has 250dp bottom margin
And I need to set the bottom margin programmatically to 0dp then set it back to 250dp, I have tried this but it's working just to set it 0dp and it doesn't work setting it to 250dp back:

    ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) linearLayoutRv.getLayoutParams();
                params.setMargins(0,0,0,250); // params.setMargins(0,0,0,0); at first
                linearLayoutRv.setLayoutParams(params);

There's some unnecessary things but here's the xml file :

    &lt;androidx.constraintlayout.widget.ConstraintLayout 
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;&gt;

    &lt;LinearLayout
        android:id=&quot;@+id/linearLayoutRv&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        android:layout_marginTop=&quot;10dp&quot;
        android:layout_marginBottom=&quot;250dp&quot;
        android:gravity=&quot;center&quot;
        android:orientation=&quot;vertical&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;&gt;

        &lt;androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;51dp&quot;
            android:gravity=&quot;center&quot;&gt;
            //textview
          
        &lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;

        &lt;LinearLayout
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;51dp&quot;
            android:orientation=&quot;horizontal&quot;&gt;
            //some buttons
        &lt;/LinearLayout&gt;

        &lt;androidx.recyclerview.widget.RecyclerView
            android:id=&quot;@+id/recyclerView&quot;
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;match_parent&quot;
            android:layout_marginHorizontal=&quot;5dp&quot;
            android:padding=&quot;4dp&quot;
            android:scrollbars=&quot;vertical&quot; /&gt;
    &lt;/LinearLayout&gt;

答案1

得分: 0

问题在于setMargins接受的值不是以dp(密度无关像素)为单位,而是以px(像素)为单位。

在将其传递给params对象之前,您必须将值250转换为dp

Context context = ...; // 如果您在Activity中,可以使用'this';如果您在Fragment中,可以使用'requireContext()'
Resources res = context.getResources();
float dp250 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 250, res.getDisplayMetrics());

ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) linearLayoutRv.getLayoutParams();
params.setMargins(0, 0, 0, dp250);
linearLayoutRv.setLayoutParams(params);

dp250将在不同设备上产生不同数量的像素。这取决于分辨率和物理屏幕大小。

英文:

The problem is that setMargins accepts values not in dp (density independent pixels) unit but in px (pixel) unit.

You must convert your value of 250 to dp before passing it to the params object.

Context context = ...; // place &#39;this&#39; if you are in an Activity or &#39;requireContext()&#39; if you are in a Fragment
Resources res = context.getResources();
float dp250 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 250, res.getDisplayMetrics());

ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) linearLayoutRv.getLayoutParams();
params.setMargins(0, 0, 0, dp250);
linearLayoutRv.setLayoutParams(params);

dp250 will result in a different number of pixels on different devices. It depends on the resolution and physical screen size.

答案2

得分: 0

当您以编程方式设置边距时,您需要以像素为单位设置值,而不是dp。LayoutParams的来源:

         /**
         * 以像素为单位设置边距。需要调用 {@link android.view.View#requestLayout()} 以便新边距得到考虑。
         * 根据布局方向,左右边距可能会被 {@link android.view.View#requestLayout()} 覆盖。
         * 边距值应该是正数。
         *
         * @param left 左边距大小
         * @param top 顶部边距大小
         * @param right 右边距大小
         * @param bottom 底部边距大小
         *
         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginLeft
         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop
         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginRight
         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom
         */
        public void setMargins(int left, int top, int right, int bottom) {
            leftMargin = left;
            topMargin = top;
            rightMargin = right;
            bottomMargin = bottom;
            mMarginFlags &amp;= ~LEFT_MARGIN_UNDEFINED_MASK;
            mMarginFlags &amp;= ~RIGHT_MARGIN_UNDEFINED_MASK;
            if (isMarginRelative()) {
                mMarginFlags |= NEED_RESOLUTION_MASK;
            } else {
                mMarginFlags &amp;= ~NEED_RESOLUTION_MASK;
            }
        }

您需要将dp转换为像素:

int yourDP = 250;
Resources r = getResources();
float px = TypedValue.applyDimension(
    TypedValue.COMPLEX_UNIT_DIP,
    yourDP,
    r.getDisplayMetrics()
);
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) linearLayoutRv.getLayoutParams();
params.setMargins(0, 0, 0, (int) px); // 最初 params.setMargins(0,0,0,0);
linearLayoutRv.setLayoutParams(params);
英文:

When you set margins programatically, you set value in pixels, not dp. Source of LayoutParams:

         /**
         * Sets the margins, in pixels. A call to {@link android.view.View#requestLayout()} needs
         * to be done so that the new margins are taken into account. Left and right margins may be
         * overridden by {@link android.view.View#requestLayout()} depending on layout direction.
         * Margin values should be positive.
         *
         * @param left the left margin size
         * @param top the top margin size
         * @param right the right margin size
         * @param bottom the bottom margin size
         *
         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginLeft
         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop
         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginRight
         * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom
         */
        public void setMargins(int left, int top, int right, int bottom) {
            leftMargin = left;
            topMargin = top;
            rightMargin = right;
            bottomMargin = bottom;
            mMarginFlags &amp;= ~LEFT_MARGIN_UNDEFINED_MASK;
            mMarginFlags &amp;= ~RIGHT_MARGIN_UNDEFINED_MASK;
            if (isMarginRelative()) {
                mMarginFlags |= NEED_RESOLUTION_MASK;
            } else {
                mMarginFlags &amp;= ~NEED_RESOLUTION_MASK;
            }
        }

You need convert your dp to pixels:

Int yourDP = 250
Resources r = getResources();
float px = TypedValue.applyDimension(
    TypedValue.COMPLEX_UNIT_DIP,
    yourDP,
    r.getDisplayMetrics()
);
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) linearLayoutRv.getLayoutParams();
            params.setMargins(0,0,0,(int) px); // params.setMargins(0,0,0,0); at first
            linearLayoutRv.setLayoutParams(params);

答案3

得分: 0

你可以很容易地使用 MotionLayout 完成这个操作。只需将父级 ConstraintLayout 转换为 MotionLayout,创建 MotionScene,然后在代码中使用 transitionToEnd()transitionToStart()

示例

英文:

You can easily do this with MotionLayout.
Just convert parent ConstraintLayout to MotionLayout, create MotionScene
and in code use transitionToEnd() and transitionToStart()

example

答案4

得分: 0

我添加了这个方法:

public static int convertDpToPixel(int dp, Context context){
    return dp * ((int) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}

并修改了这部分代码:

params.setMargins(0,0,0,convertDpToPixel(250,getContext()));
英文:

it was working but in pixels, so i added this method:

public static int convertDpToPixel(int dp, Context context){
    return dp * ((int) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}

and changed this:

params.setMargins(0,0,0,convertDpToPixel(250,getContext()));

huangapple
  • 本文由 发表于 2020年7月21日 18:15:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/63012303.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定