如何在 android 中创建水平滚动网格视图?
How to create horizontal scrolling grid view in android?
我想创建一个可以水平滚动的网格视图(不是回收视图)。我该怎么做?
好处是您可以避免从支持库中添加回收器视图并最小化 apk 大小。
回答 1
如果列表中的项目有限(如果它包含大位图,即使创建 10 个这样的项目也可能导致堆栈溢出,如果只是文本,您可能会继续处理 50-100 个项目甚至更多),请使用HorizontalScrollView.
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:padding="10dp">
<LinearLayout
android:id="@+id/hgrid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:orientation="horizontal" />
</HorizontalScrollView>
然后在您的 onCreate()
方法中将项目添加到 LinearLayout
LinearLayout layout = findViewById('hgrid');
if(layout.getChildCount()==0){
// add views to layout
}
答案 2 - 也经过测试和工作
找到了一个有点棘手的答案,但如果仔细实施,效果很好。
看似简单,就是将GridView旋转90度,然后将GridView中的item旋转-90度。但是这样做时会出现布局大小调整问题 - 解释如下。
即使旋转了 GridView,父布局也会根据未旋转的 GridView 的尺寸分配 space。这将使 GridView 消失。
解决方法
将 GridView 封装在 FrameLayout 中。现在根据您希望看到的水平GridView的实际尺寸来设置FrameLayout的尺寸。
activity.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<GridView android:id="@+id/photoGrid"
android:listSelector="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:clickable="true"
android:singleLine="true"
android:text="@string/photos"
android:textColor="#000000"
android:textSize="16sp"
android:focusable="true" />
<TextView
android:padding="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:fontFamily="sans-serif-medium"
android:text="@string/all_photos"
android:textColor="#2196F3"
android:textSize="14sp" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<GridView android:id="@+id/clgGrid"
android:listSelector="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:clickable="true"
android:singleLine="true"
android:text="@string/collages"
android:textColor="#000000"
android:textSize="16sp"
android:focusable="true" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<GridView android:id="@+id/cameraGrid"
android:listSelector="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:clickable="true"
android:singleLine="true"
android:text="@string/camera"
android:textColor="#000000"
android:textSize="16sp"
android:focusable="true" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<GridView android:id="@+id/drawingGrid"
android:listSelector="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:clickable="true"
android:singleLine="true"
android:text="@string/drawing"
android:textColor="#000000"
android:textSize="16sp"
android:focusable="true" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<GridView android:id="@+id/colorBgGrid"
android:listSelector="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:clickable="true"
android:singleLine="true"
android:text="@string/color_backgrounds"
android:textColor="#000000"
android:textSize="16sp"
android:focusable="true" />
</FrameLayout>
</LinearLayout>
</ScrollView>
现在在你身上Activity
int[] gridIds = new int[]{R.id.photoGrid, R.id.clgGrid, R.id.cameraGrid, R.id.drawingGrid, R.id.colorBgGrid};
GridView[] grids = new GridView[gridIds.length];
for(int i = 0; i<gridIds.length; i++) grids[i] = findViewById(gridIds[i]);
ViewGroup.LayoutParams params = grids[photo].getLayoutParams();
ViewGroup.MarginLayoutParams params1 = (ViewGroup.MarginLayoutParams) grids[photo].getLayoutParams();
for(int i = 0; i<gridIds.length; i++) {
grids[i].setRotation(-90);
params.height = size.x;
grids[i].setLayoutParams(params);
params1.topMargin = -size.x/2 + imgSize - 15*dp;
grids[i].setLayoutParams(params1);
grids[i].setAdapter(new cAdapter(cursor, 0));
}
现在在你的内部适配器
public class holder {
holder(View v){
img = v.findViewById(R.id.img);
txt = v.findViewById(R.id.txt);
}
ImageView img;
TextView txt;
}
public class cAdapter extends CursorAdapter {
cAdapter(Cursor c, int flags) {
super(mContext, c, flags);
}
@Override
public int getCount() {
int c = super.getCount();
return c < MAX_IMG ? c : MAX_IMG;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = LayoutInflater.from(mContext).inflate(R.layout.li_main, parent, false);
v.setTag(new holder(v));
return v;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
holder h = (holder) view.getTag();
final String imgPath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
int rotation = 90;
try {
ExifInterface ei = new ExifInterface(imgPath);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation){
case ExifInterface.ORIENTATION_ROTATE_90:
rotation += 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotation += 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotation += 270;
break;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
h.img.setRotationX(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
h.img.setRotationY(180);
break;
}
} catch (IOException ignored) {}
h.img.setRotation(rotation);
Bitmap b = MediaStore.Images.Thumbnails.getThumbnail(cr, cursor.getLong(0), MediaStore.Images.Thumbnails.MINI_KIND, null);
h.img.setImageBitmap(getRoundedCornerBitmap(b, 6*dp));
h.img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(mContext, ImageEditActivity.class).putExtra("path", imgPath));
}
});
}
}
我想创建一个可以水平滚动的网格视图(不是回收视图)。我该怎么做?
好处是您可以避免从支持库中添加回收器视图并最小化 apk 大小。
回答 1
如果列表中的项目有限(如果它包含大位图,即使创建 10 个这样的项目也可能导致堆栈溢出,如果只是文本,您可能会继续处理 50-100 个项目甚至更多),请使用HorizontalScrollView.
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:padding="10dp">
<LinearLayout
android:id="@+id/hgrid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:orientation="horizontal" />
</HorizontalScrollView>
然后在您的 onCreate()
方法中将项目添加到 LinearLayout
LinearLayout layout = findViewById('hgrid');
if(layout.getChildCount()==0){
// add views to layout
}
答案 2 - 也经过测试和工作
找到了一个有点棘手的答案,但如果仔细实施,效果很好。
看似简单,就是将GridView旋转90度,然后将GridView中的item旋转-90度。但是这样做时会出现布局大小调整问题 - 解释如下。
即使旋转了 GridView,父布局也会根据未旋转的 GridView 的尺寸分配 space。这将使 GridView 消失。
解决方法
将 GridView 封装在 FrameLayout 中。现在根据您希望看到的水平GridView的实际尺寸来设置FrameLayout的尺寸。
activity.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<GridView android:id="@+id/photoGrid"
android:listSelector="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:clickable="true"
android:singleLine="true"
android:text="@string/photos"
android:textColor="#000000"
android:textSize="16sp"
android:focusable="true" />
<TextView
android:padding="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:fontFamily="sans-serif-medium"
android:text="@string/all_photos"
android:textColor="#2196F3"
android:textSize="14sp" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<GridView android:id="@+id/clgGrid"
android:listSelector="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:clickable="true"
android:singleLine="true"
android:text="@string/collages"
android:textColor="#000000"
android:textSize="16sp"
android:focusable="true" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<GridView android:id="@+id/cameraGrid"
android:listSelector="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:clickable="true"
android:singleLine="true"
android:text="@string/camera"
android:textColor="#000000"
android:textSize="16sp"
android:focusable="true" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<GridView android:id="@+id/drawingGrid"
android:listSelector="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:clickable="true"
android:singleLine="true"
android:text="@string/drawing"
android:textColor="#000000"
android:textSize="16sp"
android:focusable="true" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<GridView android:id="@+id/colorBgGrid"
android:listSelector="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:clickable="true"
android:singleLine="true"
android:text="@string/color_backgrounds"
android:textColor="#000000"
android:textSize="16sp"
android:focusable="true" />
</FrameLayout>
</LinearLayout>
</ScrollView>
现在在你身上Activity
int[] gridIds = new int[]{R.id.photoGrid, R.id.clgGrid, R.id.cameraGrid, R.id.drawingGrid, R.id.colorBgGrid};
GridView[] grids = new GridView[gridIds.length];
for(int i = 0; i<gridIds.length; i++) grids[i] = findViewById(gridIds[i]);
ViewGroup.LayoutParams params = grids[photo].getLayoutParams();
ViewGroup.MarginLayoutParams params1 = (ViewGroup.MarginLayoutParams) grids[photo].getLayoutParams();
for(int i = 0; i<gridIds.length; i++) {
grids[i].setRotation(-90);
params.height = size.x;
grids[i].setLayoutParams(params);
params1.topMargin = -size.x/2 + imgSize - 15*dp;
grids[i].setLayoutParams(params1);
grids[i].setAdapter(new cAdapter(cursor, 0));
}
现在在你的内部适配器
public class holder {
holder(View v){
img = v.findViewById(R.id.img);
txt = v.findViewById(R.id.txt);
}
ImageView img;
TextView txt;
}
public class cAdapter extends CursorAdapter {
cAdapter(Cursor c, int flags) {
super(mContext, c, flags);
}
@Override
public int getCount() {
int c = super.getCount();
return c < MAX_IMG ? c : MAX_IMG;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = LayoutInflater.from(mContext).inflate(R.layout.li_main, parent, false);
v.setTag(new holder(v));
return v;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
holder h = (holder) view.getTag();
final String imgPath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
int rotation = 90;
try {
ExifInterface ei = new ExifInterface(imgPath);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation){
case ExifInterface.ORIENTATION_ROTATE_90:
rotation += 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotation += 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotation += 270;
break;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
h.img.setRotationX(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
h.img.setRotationY(180);
break;
}
} catch (IOException ignored) {}
h.img.setRotation(rotation);
Bitmap b = MediaStore.Images.Thumbnails.getThumbnail(cr, cursor.getLong(0), MediaStore.Images.Thumbnails.MINI_KIND, null);
h.img.setImageBitmap(getRoundedCornerBitmap(b, 6*dp));
h.img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(mContext, ImageEditActivity.class).putExtra("path", imgPath));
}
});
}
}