【问题标题】:Change width of view dynamically doesn't work动态更改视图宽度不起作用
【发布时间】:2017-07-19 10:30:26
【问题描述】:

我将主要布局分为 4 个部分。第一部分是一个图像视图,它有 layout_weight="2" 和两个线性布局,每个布局都有 layout_weight="1"。在每个线性布局中都有 2 个水平方向的 CardView,我想以相同的宽度和高度显示它们。

我改变了每个 CardView 的宽度,如下所示:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.home_page);

    CardView cardView1 = (CardView) findViewById(R.id.cardView1);
    ViewGroup.LayoutParams params = cardView1.getLayoutParams();

    params.width = params.height; // params.height == -1 ???
    cardView1.setLayoutParams(params);
}

你知道问题出在哪里吗?谢谢。

Xml 文件是:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="4">

<ImageView
    android:id="@+id/userImage"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="2"/>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:orientation="horizontal"
    android:layout_weight="1"
    android:weightSum="2">

    <android.support.v7.widget.CardView
        android:id="@+id/cardView1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:cardCornerRadius="4dp"
        android:elevation="5dp"
        app:cardElevation="10dp"
        android:paddingBottom="15dp"
        android:paddingEnd="15dp"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:paddingStart="15dp"
        android:paddingTop="15dp"
        android:layout_margin="15dp"
        app:cardBackgroundColor="?attr/colorButtonNormal">

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1"/>
    </android.support.v7.widget.CardView>

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/cardView2"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:elevation="5dp"
        card_view:cardCornerRadius="4dp"
        card_view:cardElevation="10dp"
        android:paddingBottom="15dp"
        android:paddingEnd="15dp"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:paddingStart="15dp"
        android:paddingTop="15dp"
        android:layout_margin="15dp"
        card_view:cardBackgroundColor="?attr/colorButtonNormal">

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="2"/>
    </android.support.v7.widget.CardView>
</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:orientation="horizontal"
    android:layout_weight="1"
    android:weightSum="2">

    <android.support.v7.widget.CardView
        android:id="@+id/cardView3"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:elevation="5dp"
        app:cardCornerRadius="4dp"
        android:background="@color/cardview_dark_background"
        app:cardBackgroundColor="?attr/colorButtonNormal"
        app:cardElevation="10dp"
        android:paddingBottom="15dp"
        android:paddingEnd="15dp"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:paddingStart="15dp"
        android:paddingTop="15dp"
        android:layout_margin="15dp">

        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="3"/>
    </android.support.v7.widget.CardView>

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/cardView4"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:elevation="5dp"
        card_view:cardCornerRadius="4dp"
        card_view:cardElevation="10dp"
        android:paddingBottom="15dp"
        android:paddingEnd="15dp"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:paddingStart="15dp"
        android:paddingTop="15dp"
        android:layout_margin="15dp"
        card_view:cardBackgroundColor="?attr/colorButtonNormal">

        <TextView
            android:id="@+id/textView4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="4"/>
    </android.support.v7.widget.CardView>
</LinearLayout>

【问题讨论】:

    标签: android width programmatically


    【解决方案1】:

    这是因为视图尚未调整大小,试试这个:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        final CardView cardView1 = (CardView) findViewById(R.id.cardView1);
    
        cardView1.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                // remove the layout listener
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    cardView1.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                } else {
                    cardView1.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }
    
                final int height = cardView1.getHeight(); 
                if (height >= 0) {
                    // use the linearLayout LayoutParams
                    LinearLayout.LayoutParams newParams =  new LinearLayout.LayoutParams(height, height);
                    cardView1.setLayoutParams(newParams);
                }
            }
        });
    }
    

    【讨论】:

    • 高度计算正确,但是cardView1.setLayoutParams(params);不工作
    • 请检查编辑,如果有任何不同,请告诉我
    【解决方案2】:

    如果您的问题是将您的视图显示为 Square,即宽度和高度应该相等,您可以轻松操作 OnMeasure() 视图方法。
    由于您的视图是CardView,我正在修改它,

    import android.content.Context;
    import android.support.v7.widget.CardView;
    import android.util.AttributeSet;
    
    public class SquareCardView extends CardView {
    
        public SquareCardView(Context context) {
            super(context);
        }
    
        public SquareCardView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public SquareCardView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
            int width = getMeasuredWidth();
            //noinspection SuspiciousNameCombination
            setMeasuredDimension(width, width); // here comes manipulation
        }
    }
    

    你就完成了:) 定义widthheight 将等于width

    【讨论】:

      【解决方案3】:

      试试这个,你就会知道如何在 LinearLayout 中使用权重。

      <LinearLayout
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical"
          android:weightSum="2">
      
          <LinearLayout
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1">
      
              <!--Place your image view here-->
      
          </LinearLayout>
      
          <LinearLayout
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1"
              android:orientation="vertical"
              android:weightSum="2">
      
              <LinearLayout
                  android:layout_width="match_parent"
                  android:layout_height="0dp"
                  android:layout_weight="1"
                  android:orientation="horizontal"
                  android:weightSum="2">
      
                  <LinearLayout
                      android:layout_width="0dp"
                      android:layout_height="match_parent"
                      android:layout_weight="1">
      
                      <!--CardView 1st-->
      
                  </LinearLayout>
      
                  <LinearLayout
                      android:layout_width="0dp"
                      android:layout_height="match_parent"
                      android:layout_weight="1">
      
                      <!--CardView 2nd-->
                  </LinearLayout>
      
              </LinearLayout>
      
              <LinearLayout
                  android:layout_width="match_parent"
                  android:layout_height="0dp"
                  android:layout_weight="1"
                  android:orientation="horizontal"
                  android:weightSum="2">
      
                  <LinearLayout
                      android:layout_width="0dp"
                      android:layout_height="match_parent"
                      android:layout_weight="1">
      
                      <!--CardView 3rd-->
      
                  </LinearLayout>
      
                  <LinearLayout
                      android:layout_width="0dp"
                      android:layout_height="match_parent"
                      android:layout_weight="1">
      
                      <!--CardView 4th-->
      
                  </LinearLayout>
      
              </LinearLayout>
      
          </LinearLayout>
      
      </LinearLayout>
      

      【讨论】:

        【解决方案4】:

        在屏幕上绘制之前,您会提前获得视图高度。更好的方法是首先使用像这样的观察者获取屏幕宽度

        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        view.getWidth(); //width is ready here
                         // assign your image view the same height
                        // divide this width by 2 and assign same height width to your cars views 
                    }
                });
        

        您可以关注this线程了解更多详情

        【讨论】:

        • 如何设置view.height? view.setLayoutParam() 不起作用
        【解决方案5】:

        如果您希望该视图是方形的,最好通过扩展目标小部件类来创建它,如下所示:

         public  class SquareView extends  View{
        
            public SquareView(Context context) {
                super(context);
            }
        
            @Override
            public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                super.onMeasure(widthMeasureSpec, widthMeasureSpec);
            }
        }
        

        只需指定视图的宽度,它就会把它作为高度来形成一个正方形。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-24
          • 1970-01-01
          • 1970-01-01
          • 2015-09-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多