android gridview header solution with adapter recycling cells

久未见 提交于 2019-12-03 21:24:20

I've spend a lot of time trying to set correct header to GridView. No sucess. It seems, that implementing custom GridView (inherited from ListView) is the only reasonable way. Here is an example of such GridView with headers and footers: https://github.com/SergeyBurish/HFGridView

You can try to use the following library https://github.com/maurycyw/HeaderGridView It may be helpful.

I did custom grid view with header of Images from sdcard location source. My entire project i am placing below. If it's help full to any one please vote me to increase reputations.

public class MainActivity extends Activity {
    private File file;

    LinearLayout linear;
    ArrayList<Bitmap> listbitmap;
    String[] folderlist ;
    ExpandableHeightGridView gridview;
    LinearLayout linearhere;
    String imageInSD = Environment.getExternalStorageDirectory().getAbsolutePath() +"/Hi";

    ArrayList<String> mylist = new ArrayList<String>();


    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        linear = (LinearLayout) findViewById(R.id.linear);
        File imagesSource = new File(imageInSD);
        File[] dictoryFiles = imagesSource.listFiles();

        for(int i =0; i<dictoryFiles.length;i++){
            mylist.add(dictoryFiles[i].getName());
        }

        folderlist = mylist.toArray(new String[mylist.size()]);

        linearhere = new LinearLayout(getApplicationContext());
        linearhere.setOrientation(LinearLayout.VERTICAL);
        for (int k = 0; k < folderlist.length; k++) {



            TextView textview = new TextView(getApplicationContext());
            textview.setTextColor(Color.BLACK);
            textview.setTextSize(20);
            textview.setText(folderlist[k]);

            gridview = new ExpandableHeightGridView(getApplicationContext());
            gridview.setId(Calendar.SECOND);

            gridview.setLayoutParams(new GridView.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
            gridview.setBackgroundColor(Color.WHITE);
            gridview.setNumColumns(3);
            gridview.setColumnWidth(GridView.AUTO_FIT);
            gridview.setVerticalSpacing(5);
            gridview.setHorizontalSpacing(5);
            gridview.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);


            listbitmap = new ArrayList<Bitmap>();
            file = new File(imageInSD + "/" + folderlist[k]);
            File list[] = file.listFiles();

            for (int i = 0; i < list.length; i++) {

                String sp=list[i].getName();
                //if(sp.startsWith("123")){
                    //textview.setText(folderlist[k]);
                File image = new File(imageInSD + "/"+folderlist[k]+"/" + list[i].getName());

                InputStream fis = null;
                try {
                    fis = new FileInputStream(image.getAbsolutePath());
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 2;
                Bitmap bm = BitmapFactory.decodeStream(fis, null, options);
                listbitmap.add(bm);
                //}
            }
            gridview.setAdapter(new CustomGridAdapter(getApplicationContext(),
                    listbitmap));
            gridview.setExpanded(true);

            linearhere.addView(textview);
            linearhere.addView(gridview);

        }

        linear.addView(linearhere);

    }

}

======================
class2
======================

public class ExpandableHeightGridView extends GridView
{

    boolean expanded = false;

    public ExpandableHeightGridView(Context context)
    {
        super(context);
    }

    public ExpandableHeightGridView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public ExpandableHeightGridView(Context context, AttributeSet attrs,
            int defStyle)
    {
        super(context, attrs, defStyle);
    }

    public boolean isExpanded()
    {
        return expanded;
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        // HACK! TAKE THAT ANDROID!
        if (isExpanded())
        {
            // Calculate entire height by providing a very large height hint.
            // View.MEASURED_SIZE_MASK represents the largest height possible.
            int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
                    MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);

            ViewGroup.LayoutParams params = getLayoutParams();
            params.height = getMeasuredHeight();
        }
        else
        {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    public void setExpanded(boolean expanded)
    {
        this.expanded = expanded;
    }
}

======================
class 3:
======================
public class CustomGridAdapter extends BaseAdapter {

    private Context context;
    private final ArrayList<Bitmap> gridValues;

    // Constructor to initialize values
    public CustomGridAdapter(Context context, ArrayList<Bitmap> gridValues) {

        this.context = context;
        this.gridValues = gridValues;
    }

    @Override
    public int getCount() {

        // Number of times getView method call depends upon gridValues.length
        return gridValues.size();
    }

    @Override
    public Object getItem(int position) {

        return position;
    }

    @Override
    public long getItemId(int id) {

        return id;
    }

    // Number of times getView method call depends upon gridValues.length

    public View getView(int position, View convertView, ViewGroup parent) {

        // LayoutInflator to call external grid_item.xml file

        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View gridView;

        if (convertView == null) {

            gridView = new View(context);

            // get layout from grid_item.xml ( Defined Below )

            gridView = inflater.inflate(R.layout.grid_item, null);

            ImageView imageView = (ImageView) gridView
                    .findViewById(R.id.grid_item_image);

            imageView.setImageBitmap(gridValues.get(position));

        } else {

            gridView = (View) convertView;
        }

        return gridView;
    }
}
=========================
activity_main.xml Code:
=========================

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"

    android:layout_height="wrap_content" >

            <LinearLayout
                android:id="@+id/linear"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="#D8D8D8"

                android:orientation="vertical" >

            </LinearLayout>


</ScrollView>

==========================
grid_item.xml code:
==========================

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="5dp" >

    <ImageView
        android:id="@+id/grid_item_image"
        android:layout_width="180dp"
        android:layout_margin="5dp"
        android:layout_height="150dp"
        >
    </ImageView>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="0dp" >

    </LinearLayout>

</LinearLayout>

I'm a little late to answer but in my experience this is possible through the RecyclerView api using GridLayoutManager.SpanSizeLookup helper class. For example, you can do the following in your Activity/Fragment.

mRecyclerView = (RecyclerView) view.findViewById(R.id.your_recycler_view);
mLayoutManager = new GridLayoutManager(mContext, 2);
mLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
        if (position == 0) {
            return 2;
        } else {
            return 1;
        }
    }
});
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new RecyclerAdapter();
mRecyclerView.setAdapter(mAdapter);

If the your at the beginning of the grid (position == 0), your ViewHolder will get the maximum column span, which is 2 in this situation. In your adapter class you will want to specify constants for your view types of header and items and override the int getItemViewType(int position) method to return the view type based on the adapter position. Then in RecyclerView.ViewHolder onCreateViewHolder(ViewGroup container, int viewType) inflate the appropriate layout based on the current viewType.

Hopefully this helps future readers. Surprisingly, I haven't seen this solution around for similar questions on GridView headers.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!