Решение для заголовка андроида gridview с адаптерами

Я видел много решений о том, как реализовать заголовок gridview, который прокручивается вместе с остальной частью сетки.

Большинство из них состоят в создании listlayout или relativelayout с представлением заголовка и gridview внутри scrollview. У этого решения есть проблема, что scrollview не знает размер сетки, чтобы преодолеть это, вам нужно расширить вид сетки, как здесь: https://stackoverflow.com/a/4536955/751180

Но проблема в том, что, но при этом вы вынуждаете gridview отображать все элементы сразу, не перерабатывая свои ячейки. Вероятно, это приведет к сбою приложения из-за интенсивного использования памяти, особенно если представления содержат изображения.

Другие люди используют Listviews и вычисляют, сколько столбцов можно разместить в зависимости от размера экрана. Я лично хотел бы продолжить использование сетки.

Кто-нибудь когда-либо реализовал заголовок gridview, используя другой подход?

    Я потратил много времени, пытаясь установить правильный заголовок в GridView. Нет успеха. Кажется, что реализация пользовательского GridView (унаследованного от ListView) является единственным разумным способом. Вот пример такого GridView с верхними и нижними колонтитулами: https://github.com/SergeyBurish/HFGridView

    Вы можете попробовать использовать следующую библиотеку https://github.com/maurycyw/HeaderGridView. Это может быть полезно.

    Я сделал собственное представление сетки с заголовком изображений из источника местоположения sdcard. Весь мой проект, который я размещаю ниже. Если это поможет кому-либо, пожалуйста, проголосуйте за меня, чтобы увеличить репутацию.

    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> 

    Я немного опоздал, но по моему опыту это возможно с помощью утилиты RecyclerView api, используя вспомогательный класс GridLayoutManager.SpanSizeLookup. Например, вы можете сделать следующее в своей деятельности / фрагменте.

     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); 

    Если ваш в начале сетки (позиция == 0), ваш ViewHolder получит максимальный диапазон столбцов, который равен 2 в этой ситуации. В вашем классе адаптера вы захотите указать константы для ваших типов заголовков и элементов и переопределить метод int getItemViewType(int position) чтобы вернуть тип вида на основе позиции адаптера. Затем в RecyclerView.ViewHolder onCreateViewHolder(ViewGroup container, int viewType) соответствующий макет на основе текущего вида viewType.

    Надеюсь, это поможет будущим читателям. Удивительно, но я не видел этого решения для подобных вопросов в заголовках GridView.