【问题标题】:Android Gridview with 2 column (But different imageview width size)2列的Android Gridview(但不同的imageview宽度大小)
【发布时间】:2017-09-26 12:32:44
【问题描述】:

在 gridview 的帮助下,我希望屏幕如下所示。我可以使用 setSpanSizeLookup 添加 1 列和 2 列

但是如何添加动态宽度的两列呢?

final GridLayoutManager gridLayoutManager=new GridLayoutManager(ExploreMenuActivity.this,2);
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                if(position == 0)
                {
                    return 2;
                }else {
                    return 1;
                }
            }
        });

更新:

我使用了 google 的 Flexbox 布局。

implementation 'com.google.android:flexbox:0.3.1'

我的主要活动

 FlexboxLayoutManager flexboxLayoutManager=new FlexboxLayoutManager(ExploreMenuActivity.this);
        flexboxLayoutManager.setFlexWrap(FlexWrap.WRAP);
        flexboxLayoutManager.setAlignItems(AlignItems.STRETCH);
  recycler_ExploreProduct.setLayoutManager(flexboxLayoutManager);

我的 .xml 文件

   <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/img"
android:layout_width="@dimen/_140sdp"
android:background="@color/color_white_gray"
android:layout_height="@dimen/_140sdp"
android:scaleType="fitCenter"
android:src="@drawable/p_7" />

和我的适配器

 @Override
public void onBindViewHolder(final ViewHolder holder, int position) {


    Drawable drawable = ResourcesCompat.getDrawable(context.getResources(), aryImages[position], null);
    holder.bindTo(drawable, position);
 } 

 class ViewHolder extends RecyclerView.ViewHolder {
    ImageView imageView;

    public ViewHolder(View itemView) {
        super(itemView);
        imageView = (ImageView) itemView.findViewById(R.id.img); 
    }

    void bindTo(Drawable drawable, int position) {
        imageView.setImageDrawable(drawable);
        ViewGroup.LayoutParams lp = imageView.getLayoutParams();

        DisplayMetrics displayMetrics = new DisplayMetrics();
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        wm.getDefaultDisplay().getMetrics(displayMetrics);
        int screenWidth = displayMetrics.widthPixels;

        Log.d(TAG,"## bindTo before if");
        if (lp instanceof FlexboxLayoutManager.LayoutParams) {
            Log.d(TAG,"## bindTo inside if");
            FlexboxLayoutManager.LayoutParams flexboxLp = (FlexboxLayoutManager.LayoutParams) lp;

           if (position == 0) {
                flexboxLp.width = screenWidth / 3;

            } else if (position == 1) {
                flexboxLp.width = screenWidth / 2;

            } else if (position == 2) {
                flexboxLp.width = screenWidth / 2;

            } else if (position == 3) {
                flexboxLp.width = screenWidth / 3;

            } else if (position == 4) {
                flexboxLp.width = screenWidth / 3;

            } else if (position == 5) {
                flexboxLp.width = screenWidth / 2;

            } else if (position == 6) {
                flexboxLp.width = screenWidth;

            } else if (position == 7) {
                flexboxLp.width = screenWidth / 3;

            } else if (position == 8) {
                flexboxLp.width = screenWidth / 2;

            } else if (position == 9) {
                flexboxLp.width = screenWidth;

            } else if (position == 10) {
                flexboxLp.width = screenWidth / 2;

            } else if (position == 11) {
                flexboxLp.width = screenWidth / 3;

            } else if (position == 12) {
                flexboxLp.width = screenWidth;

            } else if (position == 13) {
                flexboxLp.width = screenWidth / 3;

            } else if (position == 14) {
                flexboxLp.width = screenWidth / 2;

            } else if (position == 15) {
                flexboxLp.width = screenWidth / 2;

            } else if (position == 16) {
                flexboxLp.width = screenWidth / 3;

            } else if (position == 17) {
                flexboxLp.width = screenWidth;

            } else if (position == 18) {
                flexboxLp.width = screenWidth / 3;
            } else if (position == 19) {
                flexboxLp.width = screenWidth / 2;
            }
    }
}

现在我可以使用上述静态条件实现输出,

当我的数据来自 API 时,我怎样才能动态地做这些事情。

【问题讨论】:

    标签: android dynamic android-recyclerview layout-manager android-gridview


    【解决方案1】:

    需要在 Recyclerview 中使用 stagard LayoutManager 才能得到需要的结果。

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/rl"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp"
        tools:context=".MainActivity"
        android:background="#ffffff"
        >
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="vertical"
            >
        </android.support.v7.widget.RecyclerView>
    </RelativeLayout>
    

    MainActivity.java

    package com.cfsuman.me.androidcode;
    
    import android.content.Context;
    import android.graphics.Color;
    import android.graphics.drawable.ColorDrawable;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.StaggeredGridLayoutManager;
    import android.view.Window;
    import android.widget.RelativeLayout;
    
    
    public class MainActivity extends AppCompatActivity {
        private Context mContext;
    
        RelativeLayout mRelativeLayout;
        private RecyclerView mRecyclerView;
    
        private RecyclerView.Adapter mAdapter;
        private RecyclerView.LayoutManager mLayoutManager;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // Request window feature action bar
            requestWindowFeature(Window.FEATURE_ACTION_BAR);
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // Get the application context
            mContext = getApplicationContext();
    
            // Change the action bar color
            getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.RED));
    
            // Get the widgets reference from XML layout
            mRelativeLayout = (RelativeLayout) findViewById(R.id.rl);
            mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    
            // Initialize a new String array
            String[] colors = {
                    "Red","Green","Blue","Yellow","Magenta","Cyan","Orange",
                    "Aqua","Azure","Beige","Bisque","Brown","Coral","Crimson"
            };
    
            /*
                StaggeredGridLayoutManager
                    A LayoutManager that lays out children in a staggered grid formation. It supports
                    horizontal & vertical layout as well as an ability to layout children in reverse.
    
                    Staggered grids are likely to have gaps at the edges of the layout. To avoid these
                    gaps, StaggeredGridLayoutManager can offset spans independently or move items
                    between spans. You can control this behavior via setGapStrategy(int).
            */
            /*
                public StaggeredGridLayoutManager (int spanCount, int orientation)
                    Creates a StaggeredGridLayoutManager with given parameters.
    
                Parameters
                    spanCount : If orientation is vertical, spanCount is number of columns.
                        If orientation is horizontal, spanCount is number of rows.
                    orientation : VERTICAL or HORIZONTAL
            */
            // Define a layout for RecyclerView
            mLayoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
            mRecyclerView.setLayoutManager(mLayoutManager);
    
            // Initialize a new instance of RecyclerView Adapter instance
            mAdapter = new ColorAdapter(mContext,colors);
    
            // Set the adapter for RecyclerView
            mRecyclerView.setAdapter(mAdapter);
       }
    }
    

    ColorAdapter.java

    package com.cfsuman.me.androidcode;
    
    import android.content.Context;
    import android.graphics.Color;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import java.util.Random;
    
    
    public class ColorAdapter extends RecyclerView.Adapter<ColorAdapter.ViewHolder>{
        private String[] mDataSet;
        private Context mContext;
        private Random mRandom = new Random();
    
        public ColorAdapter(Context context,String[] DataSet){
            mDataSet = DataSet;
            mContext = context;
        }
    
        public static class ViewHolder extends RecyclerView.ViewHolder{
            public TextView mTextView;
            public ViewHolder(View v){
                super(v);
                mTextView = (TextView)v.findViewById(R.id.tv);
            }
        }
    
        @Override
        public ColorAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
            // Create a new View
            View v = LayoutInflater.from(mContext).inflate(R.layout.custom_view,parent,false);
            ViewHolder vh = new ViewHolder(v);
            return vh;
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position){
            holder.mTextView.setText(mDataSet[position]);
            // Set a random height for TextView
            holder.mTextView.getLayoutParams().height = getRandomIntInRange(250,75);
            // Set a random color for TextView background
            holder.mTextView.setBackgroundColor(getRandomHSVColor());
        }
    
        @Override
        public int getItemCount(){
            return mDataSet.length;
        }
    
        // Custom method to get a random number between a range
        protected int getRandomIntInRange(int max, int min){
            return mRandom.nextInt((max-min)+min)+min;
        }
    
        // Custom method to generate random HSV color
        protected int getRandomHSVColor(){
            // Generate a random hue value between 0 to 360
            int hue = mRandom.nextInt(361);
            // We make the color depth full
            float saturation = 1.0f;
            // We make a full bright color
            float value = 1.0f;
            // We avoid color transparency
            int alpha = 255;
            // Finally, generate the color
            int color = Color.HSVToColor(alpha, new float[]{hue, saturation, value});
            // Return the color
            return color;
        }
    }
    

    build.gradle [依赖项]

    compile 'com.android.support:recyclerview-v7:23.0.1'
    compile 'com.android.support:cardview-v7:23.0.1'
    

    【讨论】:

      【解决方案2】:
      【解决方案3】:
      You need to use flexbox layout 
      `<com.google.android.flexbox.FlexboxLayout
                      android:id="@+id/flex_layout"
                      android:layout_width="match_parent"
                      android:layout_height="match_parent"
                      app:justifyContent="flex_start"
                      app:alignContent="flex_start"
                      app:alignItems="flex_start"
                      app:flexDirection="row"
                      app:flexWrap="wrap">
      </com.google.android.flexbox.FlexboxLayout>`  
      
      and then add view dynamically like
       `TextView rowTextView = (TextView)view.findViewById(R.id.flex_tv);
        rowTextView.setTag(items.get(i));
        rowTextView.setId(i);
        rowTextView.setText(items.get(i));
        flexboxLayout.addView(view);`
      

      请在你的 gradle 中添加 compile 'com.google.android:flexbox:0.3.0@aar'

      【讨论】:

      • 您好,感谢您的发帖,我昨天尝试了这个解决方案,没有运气
      • 如果您还在苦苦挣扎,请告诉我您遇到了什么问题...
      • 如果我使用 FlexboxLayout then ,会发生 classcast 异常,您只能在行布局内使用 Imageview,但我需要在 Center imageview 顶部对齐 3 个 imageview,而使用 Flex 布局是不可能的,并且第二个问题是我想实现上面问题中发布的之字形布局,但到目前为止,我可以调整第一个两个位置的大小,但不能调整第三个,Flexbox 布局的行为很奇怪
      • classcast 异常正在发生,因为可能是您正在将 View 添加到 flexbox 布局并且当您为其设置图像时,您没有将视图类型转换为 imageview .. 如果您仍然有 flexbox 代码你可以发帖让我检查..你可以将背景设置为 flexbox 布局并为其添加填充,以便它可以播放你的 centerimageview 滚动..我通过 flexbox 实现了同样的事情..虽然我花了一周的时间..:)
      【解决方案4】:

      对两个 ImageView 使用相同权重的 LinearLayout 类似于下面的 xml

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:orientation="horizontal"
          android:layout_height="wrap_content">
      
          <ImageView
              android:id="@+id/image1"
              android:layout_width="0dp"
              android:src="@mipmap/ic_launcher"
              android:layout_weight="1"
              android:background="#ff0000"
              android:layout_height="wrap_content"/>
      
          <ImageView
              android:id="@+id/image2"
              android:layout_width="0dp"
              android:layout_weight="1"
              android:background="#ffff00"
              android:src="@mipmap/ic_launcher"
              android:layout_height="wrap_content"/>
      </LinearLayout>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-29
        • 2014-05-22
        • 2011-05-15
        • 1970-01-01
        • 2011-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多