I have a RecyclerView which has a custom adapter that inflates a rowLayout. Each Row contains a CardView and in it some text and images as buttons. In particular i have a "like" button(ImageView) that as for now only is supposed to change imageResource on click.
I was able to set an onClicklistener in the onBindViewHolder() method and it does indeed register when i click the button, however it not only changes that buttons image but it also changes some of the other like buttons and also when i scroll down and then up again the first like button sometimes get reset.
Here is my adapter code.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener {
private ArrayList<WallPost> wallPosts;
#Override
public void onClick(View v) {
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public View view;
public ViewHolder(View v) {
super(v);
view = v;
}
}
public MyAdapter(ArrayList<WallPost> wallPosts) {
this.wallPosts = wallPosts;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
TextView name = (TextView) holder.view.findViewById(R.id.person_name);
TextView age = (TextView) holder.view.findViewById(R.id.person_age);
ImageView profile = (ImageView) holder.view.findViewById(R.id.person_photo);
TextView description = (TextView) holder.view.findViewById(R.id.description_text);
AppCompatImageView mainImage = (AppCompatImageView) holder.view.findViewById(R.id.main_image);
final ImageView likeButton = (ImageView) holder.view.findViewById(R.id.like_button);
name.setText(wallPosts.get(position).getName());
age.setText(wallPosts.get(position).getAge());
profile.setImageResource(wallPosts.get(position).getPhotoId());
description.setText(wallPosts.get(position).getDescription());
mainImage.setImageResource(wallPosts.get(position).getMainPhotoId());
likeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
likeButton.setImageResource(R.drawable.favourite_red);
}
});
}
#Override
public int getItemCount() {
return wallPosts.size();
}
}
Here is the item layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cv"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="10dp"
card_view:cardCornerRadius="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
>
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:id="#+id/person_photo"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginRight="16dp"
android:src="#drawable/placeholderprofilepic"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/person_name"
android:text="Name"
android:layout_toRightOf="#+id/person_photo"
android:layout_alignParentTop="true"
android:textSize="30sp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/person_age"
android:text="19"
android:layout_toRightOf="#+id/person_photo"
android:layout_below="#+id/person_name"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/description_text"
android:text="This is the description of the image"
android:layout_below="#id/person_age"/>
<android.support.v7.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/main_image"
android:src="#drawable/placeholderfoodimage"
android:layout_below="#+id/description_text"
android:elevation="4dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/like_button"
android:src="#drawable/favoruite_hollow"
android:layout_marginTop="10dp"
android:layout_below="#+id/main_image"
/>
</RelativeLayout>
</android.support.v7.widget.CardView>
This is due to recycling of views . You need to modify your getView() method and do these 2 things -
Modify your WallPost class to have a flag to set the like flag. Set this flag in onClickListener and update your wallPosts dataset .
wallPosts.get(position).setLike(true);
Set the like/not like image resource everytime based on the like flag you own in your list objects -
if(wallPosts.get(position).isLiked()){
likeButton.setImageResource(R.drawable.favourite_red);
} else{
likeButton.setImageResource(R.drawable.favoruite_hollow);
}
Related
Please, help to figure out why my implementation of RecyclerView doesn't show anything.
Retrieving data asynchronously and result is successfull, but don't know how to display it correctly.
Activity
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
checkAndRequestPermissions(Manifest.permission.INTERNET);
RecyclerView recyclerView = binding.recyclerView;
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
NewsAdapter adapter = new NewsAdapter();
recyclerView.setAdapter(adapter);
RssService.runRssFeed(newsList -> {
System.out.println("SIZE ----- " + newsList.size());
adapter.setItems(newsList);
});
}
}
Adapter
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> {
private final List<NewsModel> news = new ArrayList<>();
#Override
public NewsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.news_item, parent, false);
return new ViewHolder(view);
}
public void setItems(List<NewsModel> news) {
this.news.addAll(news);
notifyDataSetChanged();
}
public void clearItems() {
this.news.clear();
notifyDataSetChanged();
}
#Override
public void onBindViewHolder(#NonNull NewsAdapter.ViewHolder holder, int position) {
holder.title.setText(news.get(holder.getAdapterPosition()).getTitle());
holder.date.setText(news.get(holder.getAdapterPosition()).getDate());
holder.link.setText(news.get(holder.getAdapterPosition()).getLink());
}
#Override
public int getItemCount() {
return news.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
final TextView title, date, link;
public ViewHolder(View view) {
super(view);
title = view.findViewById(R.id.titleTxt);
date = view.findViewById(R.id.dateTxt);
link = view.findViewById(R.id.linkTxt);
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
</LinearLayout>
news_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:orientation="vertical">
<TextView
android:id="#+id/titleTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:textSize="16sp"
android:textStyle="normal"
android:typeface="sans" />
<TextView
android:id="#+id/linkTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textColor="#color/white"
android:textSize="12sp"
android:textStyle="normal"
android:typeface="sans" />
<TextView
android:id="#+id/dateTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="10dp"
android:textColor="#color/white"
android:textSize="12sp"
android:textStyle="normal"
android:typeface="sans" />
</LinearLayout>
I think It showed correctly but you can't see because your text color is white
**issue in these lines**
holder.title.setText(news.get(holder.getAdapterPosition()).getTitle());
holder.date.setText(news.get(holder.getAdapterPosition()).getDate());
holder.link.setText(news.get(holder.getAdapterPosition()).getLink());
change these like
holder.title.setText(news.get(position).getTitle());
RecyclerView is not showing at all. Only the TextView is displayed.
I looked at other questions and used all answers from previous questions.
Other answers suggested that recycler's width can't be set wrap content or that setAdapter should be called after setting layout manager and I meet these conditions.
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.main_recycler);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
final MainAdapter adapter = new MainAdapter();
recyclerView.setAdapter(adapter);
List<FirebaseProduct> firebaseProductList = new ArrayList<>();
firebaseProductList = getData(); //Here is my Firebase code
adapter.setList(firebaseProductList);
}
}
activity_main.xml
<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">
<TextView
android:id="#+id/main_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/aktualne_produkty"
android:gravity="center"
android:background="#color/colorPrimary"
android:textAppearance="#style/TextAppearance.AppCompat.Large">
</TextView>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/main_recycler"
android:layout_height="wrap_content"
android:layout_width="match_parent"
tools:listitem="#layout/card_main"
android:layout_below="#id/main_text"/>
</RelativeLayout>
MainAdapter
public class MainAdapter extends RecyclerView.Adapter<MainAdapter.MainHolder> {
private List<FirebaseProduct> productList = new ArrayList<>();
#NonNull
#Override
public MainHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_main, parent, false);
return new MainHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull MainHolder holder, int position) {
FirebaseProduct product = productList.get(position);
Log.d("Prod holder", "name - " + product.getProductName());
Log.d("Prod holder", "num - " + product.getProductNumber());
holder.nameView.setText(product.getProductName());
holder.numView.setText(product.getProductNumber());
}
#Override
public int getItemCount() {
return productList.size();
}
public void setProductList(List<FirebaseProduct> productList1){
this.productList = productList1;
notifyDataSetChanged();
}
public List<FirebaseProduct> getList(){
return productList;
}
public static class MainHolder extends RecyclerView.ViewHolder{
private TextView nameView;
private TextView numView;
public MainHolder(View itemView){
super(itemView);
nameView = itemView.findViewById(R.id.product_name);
numView = itemView.findViewById(R.id.product_count);
}
}
}
card_main
<androidx.cardview.widget.CardView
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:layout_weight="3">
<TextView
android:id="#+id/product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
</TextView>
<TextView
android:id="#+id/product_count"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/product_name">
</TextView>
</RelativeLayout>
<ImageView
android:id="#+id/product_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:contentDescription="#string/product_description">
</ImageView>
</LinearLayout>
</androidx.cardview.widget.CardView>
You are calling adapter.setList(firebaseProductList); in MainActivity but the function name in MainAdapter is setProductList(). So change it to adapter. setProductList(firebaseProductList)
Also, you want to be sure getData(); in MainActivity should return a non-empty list. you can verify it using debugger or by just adding a log statement before adapter.setList(firebaseProductList). like this:
Log.d("LIST_SIZE", firebaseProductList.size()); //this will print list size
adapter.setList(firebaseProductList); //you have to change it to adapter. setProductList(firebaseProductList)
I am making an application on leave management and I want to make my leave list layout like shown in the image I want to change the colour of list view on status change from the database. Now i just add the simple text view to show the list but i want to modify it like the image it will really helpful to me if you give me the code.
here is my java code adapter:
#NonNull
#Override
public LeaveViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.leave_list, null);
view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));
LeaveViewHolder viewHolder = new LeaveViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull LeaveViewHolder holder, int position) {
LeaveModel leave = leaveList.get(position);
holder.tVFrom_date.setText("From: " + leave.getFrom_date());
holder.tVTo_date.setText("To: " + leave.getTo_date());
holder.tVStatus.setText("Status: " + leave.getLeavestatus());
if (holder.tVStatus == null) {
} else {
}
}
#Override
public int getItemCount() {
return leaveList.size();
}
public class LeaveViewHolder extends RecyclerView.ViewHolder {
protected TextView tVFrom_date, tVTo_date, tVStatus;
public View container;
public LeaveViewHolder(View itemView) {
super(itemView);
tVFrom_date = itemView.findViewById(R.id.tVFrom_date);
tVTo_date = itemView.findViewById(R.id.tVTo_date);
tVStatus = itemView.findViewById(R.id.tVStatus);
}
}
Here is my Xml layout:
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="5dp"
card_view:cardPreventCornerOverlap="false"
card_view:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="6dp"
android:paddingStart="6dp">
<TextView
android:id="#+id/tVFrom_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textColor="#color/Black"/>
<TextView
android:id="#+id/tVTo_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tVFrom_date"
android:layout_marginTop="5dp"
android:textColor="#color/Black"/>
<TextView
android:id="#+id/tVStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tVTo_date"
android:layout_marginTop="5dp"
android:textColor="#color/Red"
android:textStyle="bold" />
</RelativeLayout>
</android.support.v7.widget.CardView>
I have added image view in your layout so change color of this image view as par the status
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="5dp"
card_view:cardPreventCornerOverlap="true"
card_view:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/img_LeaveAdapter_highlight"
android:layout_width="8dp"
android:layout_height="match_parent"
android:background="#color/colorPrimary" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="6dp"
android:paddingStart="6dp">
<TextView
android:id="#+id/tVFrom_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textColor="#color/Black" />
<TextView
android:id="#+id/tVTo_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tVFrom_date"
android:layout_marginTop="5dp"
android:textColor="#color/Black"
/>
<TextView
android:id="#+id/tVStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tVTo_date"
android:layout_marginTop="5dp"
android:textColor="#color/Red"
android:textStyle="bold" />
</RelativeLayout>
</LinearLayout>
and i have created adapter just for your understanding
public class LeaveAdapter extends RecyclerView.Adapter<LeaveAdapter.MyViewHolder> {
Activity activity;
ArrayList<LeaveModel> list;
public LeaveAdapter(Activity activity, ArrayList<LeaveModel> list) {
this.activity = activity;
this.list = list;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_leaveadapter, parent, false);
return new MyViewHolder(rootView);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
String leaveStatus = list.get(position).getLeaveStatus();
if (leaveStatus.equals("Panding for approval")) {
holder.img_LeaveAdapter_highlight.setBackgroundColor(ContextCompat.getColor(activity, R.color.Red));
} else if (leaveStatus.equals("Approved")) {
holder.img_LeaveAdapter_highlight.setBackgroundColor(ContextCompat.getColor(activity, R.color.Green));
}
}
#Override
public int getItemCount() {
return list.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
ImageView img_LeaveAdapter_highlight;
public MyViewHolder(View itemView) {
super(itemView);
img_LeaveAdapter_highlight = itemView.findViewById(R.id.img_LeaveAdapter_highlight);
}
}
}
You have 2 options here:
In your RelativeLayout, add FrameLayout empty element and align left parent with full height and ~5dp width. Then in your onBindViewHolder() set FrameLayout background colour as you need. Of course, this option is simple shape (Rectangle)
If the shape you want is specific, also in RelativeLayout, add .PNG image and set backgroundTint programmatically
I'm working to make a cool layout like this:
For this I'm using Android Parallax library from Github.
This library is creating all the views (as shown in picture) from xml itself.
But I want to create my own recyclerview, create adpaters, model classes and show them with cardview.
I tried using cardview and recyclerview.
Problem:
When I put RecyclerView's height as match_parent (android:layout_height="match_parent"), it gives UI like this:
Only first cardview is display with half part only. Other cardviews are overlapped somehow.
But when I give its height with fixed height like (1000dp, 2000dp), it shows the UI as expected (as shown in first figure). I think it is not a good solution to give its height fixed since data items may differ.
I don't understand what is wrong with my code. Please do suggest some solutions on this.
Following is my different views with my code.
activity_main.xml
<com.github.florent37.parallax.ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:src="#drawable/background"
android:tag="parallax=0.3" />
<TextView
style="#style/MyTitle"
android:layout_width="match_parent"
android:layout_height="160dp"
android:gravity="center"
android:tag="parallax=0.5"
android:text="My awesome title" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="150dp"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
</LinearLayout>
</FrameLayout>
</com.github.florent37.parallax.ScrollView>
card_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:layout_gravity="center"
android:layout_margin="5dp"
card_view:cardCornerRadius="2dp"
card_view:contentPadding="10dp">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Hello"
android:textStyle="bold" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView"
android:layout_marginTop="10dp"
android:text="world" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
My Adapter class is like this:
public class MyRecyclerViewAdapter extends RecyclerView
.Adapter<MyRecyclerViewAdapter
.DataObjectHolder> {
private ArrayList<ContactsModel> mDataset;
private static MyClickListener myClickListener;
public static class DataObjectHolder extends RecyclerView.ViewHolder
implements View
.OnClickListener {
TextView label;
TextView dateTime;
public DataObjectHolder(View itemView) {
super(itemView);
label = (TextView) itemView.findViewById(R.id.textView);
dateTime = (TextView) itemView.findViewById(R.id.textView2);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
//myClickListener.onItemClick(getAdapterPosition(), v);
}
}
public void setOnItemClickListener(MyClickListener myClickListener) {
this.myClickListener = myClickListener;
}
public MyRecyclerViewAdapter(ArrayList<ContactsModel> myDataset) {
mDataset = myDataset;
}
#Override
public DataObjectHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_view, parent, false);
DataObjectHolder dataObjectHolder = new DataObjectHolder(view);
return dataObjectHolder;
}
#Override
public void onBindViewHolder(DataObjectHolder holder, int position) {
holder.label.setText(mDataset.get(position).getmText1());
holder.dateTime.setText(mDataset.get(position).getmText2());
}
public void addItem(ContactsModel dataObj, int index) {
mDataset.add(index, dataObj);
notifyItemInserted(index);
}
public void deleteItem(int index) {
mDataset.remove(index);
notifyItemRemoved(index);
}
#Override
public int getItemCount() {
return mDataset.size();
}
public interface MyClickListener {
public void onItemClick(int position, View v);
}
}
In MainActivity, I have written code like this:
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new MyRecyclerViewAdapter(getDataSet());
mRecyclerView.setAdapter(mAdapter);
Fabric.with(this, new Crashlytics());
}
private ArrayList<ContactsModel> getDataSet() {
ArrayList results = new ArrayList<ContactsModel>();
for (int index = 0; index < 20; index++) {
ContactsModel obj = new ContactsModel("Some Primary Text " + index,
"Secondary " + index);
results.add(index, obj);
}
return results;
}
}
Model class is like:
public class ContactsModel {
private String mText1;
private String mText2;
ContactsModel (String text1, String text2){
mText1 = text1;
mText2 = text2;
}
public String getmText1() {
return mText1;
}
public void setmText1(String mText1) {
this.mText1 = mText1;
}
public String getmText2() {
return mText2;
}
public void setmText2(String mText2) {
this.mText2 = mText2;
}
}
Apologies for the very long bulk of code.
Thanks!
You have a RecyclerView (which is scrollable) within a Scrollable Layout.
Replace your ScrollView tag with "android.support.v4.widget.NestedScrollView". This will allow the RecyclerView to properly expand.
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
</android.support.v4.widget.NestedScrollView>
After Replaceing your ScrollView with NestedScrollView you can just add this line into the NestedScrollView
android:fillViewport="true"
I was having a same problem in my NestedScrollView.
Just added one line inside NestedScrollView and my problem solved.
android:fillViewport="true"
Recyclerview is not displayed in fullscreen. Below is the layout file and the code I've written. After executing, the contents are displayed as shown in the below picture. The height is only the highlighted part. I want the contents to be fullscreen. I remaining contents are within this highlighted area which is scrollable. I want the contents to be displayed in fullscreen. Any help would be helpful.
Layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="#+id/activity_search"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:clickable="true">
<TextView
android:id="#+id/title"
android:textSize="16dp"
android:textStyle="bold"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/genre"
android:layout_below="#id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/year"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_height="wrap_content" />
</RelativeLayout>
</LinearLayout>
Code:
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
public class setSearchData extends RecyclerView.Adapter<setSearchData.MyViewHolder> {
private List<SearchDisplayContents> moviesList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView title, year, genre;
public MyViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.title);
genre = (TextView) view.findViewById(R.id.genre);
year = (TextView) view.findViewById(R.id.year);
}
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.activity_searchresults, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
SearchDisplayContents movie = moviesList.get(position);
holder.title.setText(movie.getTitle());
holder.genre.setText(movie.getGenre());
holder.year.setText(movie.getYear());
}
#Override
public int getItemCount() {
return moviesList.size();
}
}
Calling function code:
List<SearchDisplayContents> movieList = new ArrayList<>();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
setSearchData mAdapter = new setSearchData(movieList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
SearchDisplayContents movie = new SearchDisplayContents("Mad Max: Fury Road", "Action & Adventure", "2015");
movieList.add(movie);
movie = new SearchDisplayContents("Inside Out", "Animation, Kids & Family", "2015");
movieList.add(movie);
mAdapter.notifyDataSetChanged();
You should use different layout for your viewholder. Take the RelativeLayout you have there, cut it out, put it in different xml file then pass it to onCreateViewHolder.
From look at your code - it looks like what is in the preview screenshot is the same as what is within the RelativeLayout you have staticly defined.
There is an issue with your approach. It is that you are referencing the RelativeLayout (within the same xml hierarchy as your RecylerView) as the CellViewHolder in the RecyclerView.Adapter. My approach personally is to create a seperate xml layout for the cell viewholder.
Follow this guide, it is very detailed:
https://guides.codepath.com/android/using-the-recyclerview
You should use different layout for your viewholder. Take the RelativeLayout you have there, cut it out, put it in different xml file then pass it to onCreateViewHolder.
The above coding has something work use different layout mean one for Recycleview and other for contents in list
main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/uslist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="#dimen/_49sdp"
android:divider="#android:color/transparent" />
</RelativeLayout>
list_content.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:clickable="true">
<TextView
android:id="#+id/title"
android:textSize="16dp"
android:textStyle="bold"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/genre"
android:layout_below="#id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/year"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_height="wrap_content" />
</RelativeLayout>
Adapter.java
public class yourAdapter extends RecyclerView.Adapter<yourAdapter .SimpleViewHolder> {
ArrayList<UsageRPDetails> mylist;
private Context mContext;
public yourAdapter (Context context, ArrayList<yourArray or model> checklist) {
mContext = context;
mylist = checklist;
}
#Override
public yourAdapter .SimpleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_content, parent, false);
return new yourAdapter .SimpleViewHolder(view);
}
#Override
public void onBindViewHolder(final yourAdapter .SimpleViewHolder holder, final int position) {
holder.title.setText();
holder.year.setText();
holder.genre.setText();
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public int getItemCount() {
return mylist.size();
}
#Override
public int getItemViewType(int i) {
return 0;
}
public static class SimpleViewHolder extends RecyclerView.ViewHolder {
#Bind(R.id.title)
TextView title;
#Bind(R.id.genre)
TextView genre;
#Bind(R.id.year)
TextView year;
public SimpleViewHolder(View itemView) {
super(itemView);
title= (TextView) itemView.findViewById(R.id.title);
genre= (TextView) itemView.findViewById(R.id.genre);
genre= (TextView) itemView.findViewById(R.id.genre);
}
}
}
Also write a java file for Activity that calls this adapter class and call the recycleview in this activity