How to Make Grid-View Horizontally Scrollable in Android

How to make grid-view horizontally scrollable in android

I found Two-way GridView helpful on github.

It has some methods:

scrollDirectionPortrait (vertical | horizontal)

scrollDirectionLandscape (vertical | horizontal)

numRows()

etc

How to make grid view scroll horizontally not vertically in android?

You can try putting the GridView in a HorizontalScrollView. You may try to set fixed height to the GridView inside the HorizontalScrollView.

Then you can dynamically calculate the number of columns of the GridView based on your content and use setNumColumns(int) method to set it.

Horizontal scrolling grid view

You can

  • use a TableLayout inside a HorizontalScrollView, or
  • stay with your approach with an horizontal LinearLayout but adding vertical LinearLayouts instead of directly the images. E.g., adding three to four images per vertical LinearLayout in portrait, and redrawing to add only two in landscape.

I would try the TableLayout approach first.

PS1: for next time, try to remove all the non-relevant code (the less code is there, the easier is to understand what you did).

PS2: Remember that System.out is usually redirected to /dev/null and thus lost, so I strongly suggest you to use Log.d instead.

Complete example

Adapt this to the onCreate() method or wherever you need it:

public void horizontalScrollGalleryLayout () {
HorizontalScrollView sv = new HorizontalScrollView(this);
LinearLayout llh = new LinearLayout(this);
llh.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams layoutParamsTV = new LinearLayout.LayoutParams(40, 40);
LinearLayout.LayoutParams layoutParamsLL = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
for (int i=0; i<20; i++) {
LinearLayout llv = new LinearLayout(this);
llv.setOrientation(LinearLayout.VERTICAL);
TestView testView1 = new TestView(this, Color.rgb(i*12, 0, 0));
TestView testView2 = new TestView(this, true, Color.rgb(i*12, i*12, 0));
TestView testView3 = new TestView(this, true, Color.rgb(0, i*12, 0));
llv.addView(testView1, layoutParamsTV);
llv.addView(testView2, layoutParamsTV);
llv.addView(testView3, layoutParamsTV);
llh.addView(llv, layoutParamsLL);
}
sv.addView(llh, layoutParamsLL);
setContentView(sv);
}

I'm using a very simple View as an example:

public class TestView extends View {
Context context;
int color;

public TestView(Context context, int color) {
super(context);
this.context = context;
this.color = color;
}

@Override
public void onDraw (Canvas canvas) {
super.onDraw(canvas);
this.setBackgroundColor(Color.LTGRAY);
Paint paint = new Paint (Paint.ANTI_ALIAS_FLAG);
paint.setColor(color);
canvas.drawCircle(20, 20, 20, paint);
}
}

How to create horizontal scrolling grid view in android?

Answer 2 - also tested and working

Found a bit tricky answer but it works well, if carefully implemented.

It seems as simple as rotating the GridView by 90 degree and rotating the items inside GridView by -90 degree. But when doing this there are issues with layout sizing - explained below.

Even though GridView is rotated, the parent layout allocates space as per the dimensions of GridView without rotation. This will make GridView disappear.

WorkAround

Enclose GridView inside FrameLayout. Now set the dimension of FrameLayout according to the actual dimensions of horizontal GridView that you would like to see.

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>

Now in you 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));
}

Now Inside you adapter

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

Android horizontal scroll in grid view

My suggestion would be to swap out the GridView for a RecyclerView. The RecyclerView + LayoutManager combination allows much more variety in layouts of this type. From the RecyclerView.LayoutManager documentation:

By changing the LayoutManager a RecyclerView can be used to implement a standard vertically scrolling list, a uniform grid, staggered grids, horizontally scrolling collections and more.

You would want to look at the GridLayoutManager to start with. My guess is that the orientation parameter in the constructor:

GridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout)

may allow you to set up horizontal scrolling quite easily. At worst, you may have to do some custom touch handling to manage horizontal motion.

Horizontal Gridview with a set number of rows

I ended up doing it by using a recycle view and setting a gridlayoutmanager to it.

GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2, GridLayoutManager.HORIZONTAL, false);
RecyclerView recyclerView = findViewById(R.id.DicesGridView);
recyclerView.setLayoutManager(gridLayoutManager);
DicesElementAdapter adapter = new DicesElementAdapter(this, DiceList, Result, LogsList, gson, sharedPreference);
recyclerView.setAdapter(adapter);


Related Topics



Leave a reply



Submit