我已经看到很多关于如何实现与网格其余部分一起滚动的gridview标头的解决方案。
其中大多数都是在scrollview中创建一个listlayout或relativelayout,其中包含标题视图和gridview。这个解决方案的问题是scrollview不知道网格的大小,所以要克服你需要像这里扩展网格视图:https://stackoverflow.com/a/4536955/751180
但问题是,但是这样做会迫使gridview立即呈现所有项目而不会回收其单元格。这可能会导致应用程序因大量内存使用而崩溃,特别是如果视图包含图像。
其他人正在使用Listviews并根据屏幕大小计算可以放置的列数。我个人想继续使用网格视图。
有没有人使用不同的方法实现gridview标头?
答案 0 :(得分:4)
我花了很多时间尝试为GridView设置正确的标头。没有成功。看来,实现自定义GridView(继承自ListView)是唯一合理的方法。以下是带有页眉和页脚的GridView示例:https://github.com/SergeyBurish/HFGridView
答案 1 :(得分:3)
您可以尝试使用以下库https://github.com/maurycyw/HeaderGridView 这可能会有所帮助。
答案 2 :(得分:0)
我使用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>
答案 3 :(得分:0)
我回答有点迟,但根据我的经验,这可以通过使用GridLayoutManager.SpanSizeLookup助手类的RecyclerView api实现。例如,您可以在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);
如果您在网格的开头(位置== 0),您的ViewHolder将获得最大列跨度,在这种情况下为2。在适配器类中,您需要为标头和项的视图类型指定常量,并覆盖int getItemViewType(int position)
方法以根据适配器位置返回视图类型。然后在RecyclerView.ViewHolder onCreateViewHolder(ViewGroup container, int viewType)
中根据当前的viewType夸大适当的布局。
希望这有助于未来的读者。令人惊讶的是,我还没有在GridView标题上找到类似问题的解决方案。