I'm trying to implement a RecyclerView with a GridLayoutManager in my Android application. The CardView elements within the RecyclerView are displaying vertically as if they were in a LinearLayout. How can I coerce them to fill the grid from left to right, one row at a time?
Here is my RecyclerView layout code:
<android.support.v7.widget.RecyclerView
android:id="#+id/RECYCLER_VIEW"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/item_offset" />
Here is my CardView layout code:
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/card_view"
card_view:cardUseCompatPadding="true"
android:layout_width="120dp"
android:layout_height="120dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_alignParentBottom="true"
android:textAlignment="center"
android:textSize="18dp" />
</RelativeLayout>
</android.support.v7.widget.CardView>
Here is the code to set up the RecyclerView in the activity's onCreate method (CustomAdapter extends RecyclerView.Adapter):
// set up adapter
adapter = new CustomAdapter(getApplicationContext(), ApplicationState.getGridElements());
view.setAdapter(adapter);
// grid layout manager with 2 columns
GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
view.setLayoutManager(layoutManager);
// custom decoration for equal spacing
ItemOffsetDecoration itemDecoration = new ItemOffsetDecoration(getApplicationContext(), R.dimen.item_offset);
view.addItemDecoration(itemDecoration);
view.setHasFixedSize(true);
GridLayoutManager (Context context,
int spanCount,
int orientation,
boolean reverseLayout)
Set reverseLayout as true
Related
I'm very new to android and I'm learning android from the internet by myself I want dynamic horizontal layouts. I want items as we use in css flex layouts. I want something like this
I tried some code with that code I'm getting the result something like this
I tried this code
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.72"
android:background="#drawable/main_bg_home">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:paddingTop="#dimen/_10sdp">
<androidx.cardview.widget.CardView
android:layout_width="#dimen/_230sdp"
android:layout_height="#dimen/_50sdp"
android:layout_marginTop="#dimen/_10sdp"
android:gravity="center"
app:cardBackgroundColor="#color/home_btn_bg_color"
app:cardCornerRadius="#dimen/_8sdp"
app:cardElevation="2dp">
<RelativeLayout
android:id="#+id/wsBtn"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="#dimen/_30sdp"
android:padding="#dimen/_6sdp"
android:layout_height="#dimen/_30sdp"
android:layout_centerVertical="true"
android:layout_marginLeft="#dimen/_12sdp"
android:background="#drawable/ic_icon_bg"
android:src="#drawable/whts" />
<ImageView
android:layout_width="#dimen/_12sdp"
android:layout_height="#dimen/_12sdp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="#dimen/_15sdp"
android:src="#drawable/right_arrow"
app:tint="#color/home_right_arrow_color" />
<TextView
android:id="#+id/txt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="#dimen/_60sdp"
android:text="#string/whatsapp"
android:textColor="#color/home_btn_txt"
android:textSize="#dimen/_13sdp"
android:textStyle="bold" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
</ScrollView>
</LinearLayout>
Please update your LinearLayout orientation to horizontal
look like this
android:orientation="horizontal"
It looks like you're trying to create a horizontally scrollable list of items, similar to the CSS flex layout. To achieve this in Android, you can use a RecyclerView with a LinearLayoutManager set to horizontal orientation. Here's an example code:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="horizontal">
</androidx.recyclerview.widget.RecyclerView>
And in your activity/fragment class, you can set the RecyclerView's layout manager to be a LinearLayoutManager with horizontal orientation:
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
Finally, you need to set an adapter for the RecyclerView, which will provide the data and layout for each item. Here's an example of a simple adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<String> mData;
public MyAdapter(List<String> data) {
mData = data;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.textView.setText(mData.get(position));
}
#Override
public int getItemCount() {
return mData.size();
}
static class MyViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text_view);
}
}
}
And finally, you set the adapter to the RecyclerView:
MyAdapter adapter = new MyAdapter(data);
recyclerView.setAdapter(adapter);
Replace item_view.xml with the layout you want for each item in the list and data with your data source. This is just a simple example to get you started. You can customize the adapter and item layout as needed for your use case.
For your case, better to use RecyclerView. You can see here a example that how to implement the same.
And for Grid you can use RecyclerView.GridLayoutManager(context, 2).
And for Vertical List you can use RecyclerView.LinearLayoutManager(context).
And for Horizontal List you can use RecyclerView.LineaLayoutManager(context, LinearLayoutManager.HORIZONTAL, false).
Hope this will help you:)
I have a full screen grid layout with 8 rows of 7 ImageView.
I need all the rows centered without spaces between them (now I have as result the image I uploaded). The space must be only on the top and on the bottom. I already tried to find a solution on the Internet but I haven't found one.
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<GridLayout
android:id="#+id/gameGrid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:rowCount="8"
android:columnCount="7"
>
<!-- ROW 1-1 -->
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/cellR1-1"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
app:srcCompat="#drawable/dl"
/>
<!-- ROW 1-2 -->
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/cellR1-2"
android:layout_rowWeight="1"
android:layout_columnWeight="1"
app:srcCompat="#drawable/dl"
/>
<!-- ROW ... -->
</GridLayout>
</RelativeLayout>
I tried as solution to set all the ImageViews height same as the width but my code didn't worked:
void setGrid(){
//setting the cell height as the cell widht
int imagWidth = cell[0][0].getLayoutParams().width;
for(int r=0;r<rowCount;r++)
for(int c=0;c<columnCount;c++) {
cell[r][c].getLayoutParams().height = imagWidth;
cell[r][c].requestLayout();
}
}
Image:
It might be helpful to you, use the RecyclerView instead of GridLayout
RecyclerView.LayoutManager recyclerViewLayoutManager = new GridLayoutManager(getApplicationContext(), 7); // 7 means how many column you want you can change according to your requirement.
recyclerView.setLayoutManager(recyclerViewLayoutManager);
Try using RecyclerView with GridLayoutManager like below:
GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 7);
YourAdapter adapter = new YourAdapter();
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
int spacing = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16,
Objects.requireNonNull(getContext()).getResources().getDisplayMetrics());
recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
#Override
public void getItemOffsets(#NotNull Rect outRect, #NotNull View view, #NotNull RecyclerView parent, #NotNull RecyclerView.State state) {
if (parent.getChildAdapterPosition(view) == Objects.requireNonNull(parent.getAdapter()).getItemCount() - 1) {
outRect.bottom = spacing;
}
if (parent.getChildAdapterPosition(view) == 0) {
outRect.top = spacing;
}
}
});
Other solution is:
Instead of adding padding to both the top and bottom items, You can just add the padding to the top and bottom of your RecyclerView and set the clipToPadding attribute to false.
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingTop="8dp"
android:paddingBottom="8dp" />
How to set Max Height of RecyclerView?
I have a RecyclerView as follows:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler_goods">
</android.support.v7.widget.RecyclerView>
When the items of recyclerview are too many, the recyclerview will be too high.
Can I set the max height of the recyclerview ?
when the recyclerview grow to the max height,The recyclerview will not grow up and the items of recyclerview can be scrolled.
Create a subclass of RecyclerView and override onMeasure method.
public class MyRecyclerView extends RecyclerView {
#Override
protected void onMeasure(int widthSpec, int heightSpec) {
height = MeasureSpec.makeMeasureSpec(Utils.dpsToPixels(the_height_you_want), MeasureSpec.AT_MOST);
super.onMeasure(widthSpec, height);
}
}
You can use ConstraintLayout to wrap RecyclerView and others, set their constraint and set minHeight for view belows RecyclerView
try this:
xml code
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Title"
android:textSize="21sp"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="30dp"> //increases your recycleview height
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</FrameLayout>
java code
if your item on wrap content
ViewGroup.LayoutParams params=recycler_view.getLayoutParams();
params.height= RecyclerView.LayoutParams.WRAP_CONTENT;
recycler_view.setLayoutParams(params);
and
<dimen name="view_height">250dp</dimen>
float height= getResources().getDimension(R.dimen.view_height); //get height
ViewGroup.LayoutParams params_new=recycler_view.getLayoutParams();
params_new.height=height;
recycler_view.setLayoutParams(params_new);
Simplest solution: You can put RecyclerView with android:layout_height"match_parent" in a parent layout (RelativeLayout, LinearLayout,...) with specific height.
I have searched a lot regarding my query and none of them was useful. I have a recyclerview and some static data inside a scroll view which is inside a root parentlayout as show below.
I have set -
scrollview.scrollto(0,0);
because everytime i open the activity it jumps to the recyclerview firstitem and it skips out the static data above the recyclerview.
recyclerview.setNestedScrollingEnabled(false);
recyclerview.setfocusable(false);
for smoothscroll.
the problem is with-
layoutmanager.scrollToPositionWithOffset(pos,0);
it is not working. I have set the aboveline after setting adapter to recyclerview. Also tried with NestedScrollView but in vain.
although I have used
layoutmanager.scrollToPosition(pos);
For those who skip the code, i have set match_parent to ScrollView and
fillviewport to true.
Here is my layout.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/bottomsheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.inkdrops.khaalijeb.BrandCouponActivity">
<RelativeLayout
android:id="#+id/inclusionviewgroup"
android:layout_width="match_parent"
android:layout_height="match_parent">
<static data/>
<ScrollView
android:id="#+id/scrollviewmain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/one"
android:fillViewport="true"
android:scrollbars="none"
android:layout_above="#+id/donelayout">
<staticdata/>
<TextView
android:id="#+id/dealstext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/card1"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:textSize="16sp"
android:text="Deals & Coupons"
android:textColor="#444444" />
<RelativeLayout
android:id="#+id/recyclerlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/dealstext"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="#color/colorbackground">
<android.support.v7.widget.RecyclerView
android:id="#+id/coupon_rec_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorbackground"
android:visibility="visible"/>
</RelativeLayout>
<statisdata>
</RelativeLayout>
</ScrollView>
include layout="#layout/activity_coupons"
android:visibility="gone"
/>
</RelativeLayout>
</RelativeLayout>
Need to scroll ScrollView by getting top position of RecyclerView's child :
float y = recyclerView.getY() + recyclerView.getChildAt(selectedPosition).getY();
scrollView.smoothScrollTo(0, (int) y);
you can use scroll view method to reach your desired locations as:
scrollView.smoothScrollTo(int x, int y);
Step 1: Add this line for selecting that position in the recyclerview
adaptercat.setSelectedItem(Integer.parseInt(dealtypeid));
Step 2: Once check below constructor by getting current position
public CatgerotyAdapter(Context context, ArrayList<HashMap<String, String>> arraylist,String selectedPosition) {
this.context = context;
this.data = arraylist;
resultp = new HashMap<>();
currentItemPos=Integer.parseInt(selectedPosition)-1;
}
Step 3: And this function also in adapter
public void setCurrentItem(int item)
{
this.currentItemPos = item;
}
Last step 4. Add this function outside adapter in your class
private void onPagerItemClick2(Integer tag)
{
adaptercat.setCurrentItem(tag);
catsp.setAdapter(adaptercat);
}
Pust this line in your listview item click listner
((ClassName) context).onPagerItemClick2(position);
That position will be selected when will you open listview ..
Use this method scrollToPosition (int position) this is work for me. hope this will help you.
mMessagesRecyclerView = (RecyclerView) findViewById(R.id.messagesRecyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true);
mMessagesRecyclerView.setLayoutManager(layoutManager);
mMessagesAdapter = new MessagesAdapter();
mMessagesRecyclerView.setAdapter(mMessagesAdapter);
mMessagesRecyclerView.scrollToPosition(your position);
this is my layoutstructer
Trying to replace the ListView with RecyclerView.
Not sure if someone also having problem to use RecyclerView. I noticed without changing the view item layout, using RecyclerView the scrolling is not as smooth as when using ListView, and for my view item layout only GridLayoutManager works.
Any suggestion? thanks!
The view item layout is not changed and it has been working fine with ListView (has > 1000 data).
With ListView:
<ListView
android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
public class UsingListViewAdapter extends BaseAdapter;
UsingListViewAdapter mAdaptor new UsingListViewAdapter(null, mSelectListener);
mListView = (ListView) view.findViewById(R.id.list_view);
mListView.setAdapter(mAdaptor);
with RecyclerView:
<android.support.v7.widget.RecyclerView
android:id="#+id/list_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent”/>
public class UsingRecyclerViewAdapter extends RecyclerView.Adapter< UsingRecyclerViewAdapter.RowViewHolder>
implements View.OnClickListener, View.OnLongClickListener;
UsingRecyclerViewAdapter mAdaptor new UsingRecyclerViewAdapter(null, mSelectListener)
mRecyclerView = (RecyclerView) view.findViewById(R.id.list_view);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new GridLayoutManager(getActivity(), 1);
//mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdaptor);
The view item used in the Adapters of ListView and RecyclerView are same layout, which one row has two elements side by side using layout_width=“0dp"/layout_weight=“1” to stretch to fill the row.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="top" >
<LinearLayout
android:id="#+id/row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:orientation="horizontal"
android:visibility="gone"
>
<include
android:id="#+id/row_cell_one"
layout="#layout/cell_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<include
android:id="#+id/row_cell_two"
layout="#layout/cell_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
The cell_layout is like:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/img_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/img"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="#drawable/dumy_img" />
<ImageView
android:id="#+id/overlay_img"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:background="#drawable/box_border"
android:scaleType="center"
android:src="#drawable/overlay_image"
android:tint="#color/dark_pink"
android:visibility="gone" />
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="#dimen/padding_top"
android:paddingBottom="#dimen/padding_bottom"
android:orientation="vertical" >
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/left"
android:layout_marginRight="#dimen/right"
android:ellipsize="end"
android:textSize="#dimen/text_size"
android:gravity="left"
android:singleLine="true"
android:textColor="#color/black"/>
<TextView
android:id="#+id/text_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/left"
android:layout_marginRight="#dimen/right"
android:ellipsize="end"
android:textSize="#dimen/text_size"
android:gravity="left"
android:singleLine="true"
android:textColor="#color/light_blue" />
</LinearLayout>
Both (using ListView or RecyclerView) have similar Adapter to update the View,
except in RecyclerView implemented
public RowViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
public void onBindViewHolder(RowViewHolder holder, int position)
public int getItemCount()
First notice is the the scrolling of using ListView is much much smoother than using the RecyclerView.
If use LinearLayoutManager, the items displayed in the row are messed up. The two items do not occupy full width of the display, and the element supposed to be overlay on top of other element (e.g img.top == overlay_img.top) is placed below (e.g. overlay_img.top == img.top + img.height), and with same height of white space below the overlay_img.
Only after changed to use mLayoutManager = new GridLayoutManager(getActivity(), 1); then the row is properly displayed.
with RecyclerView (using LinearLayoutManager) it is displayed as:
+---------------------+
(cell | (cell
one) | two)
+---------------------+
With ListView and RecyclerView (using GridLayoutManager) it is displayed as:
+---------------------+
(cell one) | (cell two)
+---------------------+