Item not showing inside RecyclerView - android

I check everything in my code,I ask a question and do some of the modification,and also reading all the question about "Item not showing in RecyclerView",but the layout still not appear in my recyclerView.
This is my previous question,I attach all my code here,have 3 answer tell me,I should use LinearLayout instead of RelativeLayout as the parent of RecyclerView,so I modified the code as below
Fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/commentFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/titlebar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/feed_item_margin"
android:layout_marginRight="#dimen/feed_item_margin"
android:layout_marginTop="#dimen/feed_item_margin"
android:layout_weight="1"
android:text="Be the first to like this" />
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/comment_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:animateLayoutChanges="false"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
<LinearLayout
android:id="#+id/commentInsert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:orientation="horizontal">
<EditText
android:id="#+id/commentField"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#null"
android:ems="10"
android:hint="Add a comment" />
<Button
android:id="#+id/sendButton"
android:layout_width="77dp"
android:layout_height="wrap_content"
android:text="Send" />
</LinearLayout>
</LinearLayout>
Here is the item which should be appear in the RecyclerView.comment_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_weight="1">
<ImageView
android:id="#+id/commentProfilePic"
android:layout_weight="0.05"
android:layout_width="#dimen/comment_item_profile_pic"
android:layout_height="#dimen/comment_item_profile_pic"
android:layout_marginLeft="#dimen/feed_item_margin"
android:layout_marginRight="#dimen/feed_item_margin"
android:layout_marginTop="#dimen/feed_item_margin"
android:scaleType="fitCenter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/feed_item_margin"
android:layout_marginRight="#dimen/feed_item_margin"
android:layout_marginTop="#dimen/feed_item_margin"
android:orientation="vertical"
android:layout_weight="1"
android:paddingLeft="#dimen/comment_item_profile_info_padd">
<TextView
android:id="#+id/commentUsername"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/comment_item_status_pad_left_right"
android:paddingRight="#dimen/comment_item_status_pad_left_right"
android:textStyle="bold" />
<TextView
android:id="#+id/commentBody"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/comment_item_status_pad_left_right"
android:paddingRight="#dimen/comment_item_status_pad_left_right" />
<TextView
android:id="#+id/commentTimestamp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/comment_item_status_pad_left_right"
android:paddingRight="#dimen/comment_item_status_pad_left_right"
android:paddingTop="#dimen/comment_item_timestamp_pad_top" />
</LinearLayout>
I read this issue tell that need to add this line of code adapter.notifyDataSetChanged();,I done that,this is how I notifyDataSetChanged() when I parse the JSON.
private void parseJsonFeed(JSONObject response) {
try {
JSONArray commentArray = response.getJSONArray("comment");
//get all the item in Json
for (int i = 0; i < commentArray.length(); i++) {
JSONObject commentObj = (JSONObject) commentArray.get(i);
commentId = commentObj.getInt("comment_id");
commenterUsername= commentObj.getString("commenter_username");
commentBody = commentObj.getString("comment_body");
commenterProfileImage = commentObj.getString("commenter_profile_image");
commentCreatedAt = commentObj.getString("comment_created_at");
//set all item to the Array list
setItemToCommentArrayList(commentId,commenterUsername,commenterProfileImage,commentBody,commentCreatedAt);
}
// notify data changes to list adapter
commentAdapter.notifyDataSetChanged();
}catch (JSONException e){
System.out.println("end of content");
}
}
I checked,whether is something wrong when I set my adapter to the RecycleView.So i read this answer,and here is how I set my adapter
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View dialogView = inflater.inflate(R.layout.fragment_comment, container,false);
commentRecyclerView =(RecyclerView)dialogView.findViewById(R.id.comment_recycler_view);
commentRecyclerView.setNestedScrollingEnabled(false);
//bind the recycler view with the adapter
commentAdapter = new CommentAdapter(getActivity(),commentItems);
final LinearLayoutManager myLayoutManager = new LinearLayoutManager(getActivity());
commentRecyclerView.setLayoutManager(myLayoutManager);
commentRecyclerView.setAdapter(commentAdapter);
Here is my CommentAdpater , I still didnt see any different with my another recycleview adapter.
public class CommentAdapter extends RecyclerView.Adapter<CommentAdapter.MyViewHolder>{
private Context cContext;
private List<CommentItem> commentItems;
class MyViewHolder extends RecyclerView.ViewHolder{
TextView commentBody,commentUsername,commentTimeStamp;
ImageView commentProfilePic;
//find all the view here
MyViewHolder(final View view) {
super(view);
commentProfilePic = (ImageView)view.findViewById(R.id.commentProfilePic);
commentUsername = (TextView)view.findViewById(R.id.commentUsername);
commentBody = (TextView)view.findViewById(R.id.commentBody);
commentTimeStamp = (TextView)view.findViewById(R.id.commentTimestamp);
}
}
public CommentAdapter(Context cContext, List<CommentItem> commentItems) {
this.cContext = cContext;
this.commentItems = commentItems;
}
#Override
public long getItemId(int position) {
return position;
}
//this one for make the adview inside this
#Override
public int getItemViewType(int position) {
return position;
}
//bind the comment item here
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View commentItemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.comment_item, parent, false);
return new MyViewHolder(commentItemView);
}
//do all the action here
#Override
public void onBindViewHolder(CommentAdapter.MyViewHolder holder, int position) {
final CommentItem commentItem = commentItems.get(position);
//commenter username
holder.commentUsername.setText(commentItem.getUsername());
//commenter profile image
Glide
.with(cContext)
.load(commentItem.getCommentProfilePic())
.fitCenter()
.into(holder.commentProfilePic);
//comment body
holder.commentBody.setText(commentItem.getCommentBody());
//comment timestamp
holder.commentTimeStamp.setText(commentItem.getCommentTimeStamp());
}
#Override
public int getItemCount() {
return commentItems.size();
}
}
I make sure my JSON is received in my volley Request.I log it out,is received in Volley onResponse .My JSON is look like this
"comment":[{"comment_created_at":"2017-03-21 13:03:40","comment_id":8,"comment_body":"abc","commenter_username":"abc","profile_image_path":"http:\/\/abc\/def\/v1\/ef\/defaultmale.jpg"
And this question I ask just tell me no need to worry about cause I using Glide to load my image,Glide will handle that
This is all the solution that tried,and still havent get it done,so what I still missing out here,in order the comment_xmlappear to the recyclerView inside Fragment.xml? Any guide that lead me to the right direction is well-appreciated.Thanks
UPDATE
Here is my setItemToCommentArrayList()
private void setItemToCommentArrayList(int commentId, String commenterUsername, String commenterProfileImage, String commentBody, String commentCreatedAt) {
CommentItem item = new CommentItem();
item.setCommentId(commentId);
item.setUsername(commenterUsername);
item.setCommentProfilePic(commenterProfileImage);
item.setCommentBody(commentBody);
item.setCommentTimeStamp(commentCreatedAt);
//save it to the comment array list
commentItems.add(item);
}
Here is my data model of Comment Item
public class CommentItem {
private String username,commentBody,commentTimeStamp,commentProfilePic;
private int commentId;
public CommentItem(){
}
public CommentItem(int commentId, String username,String commentBody,String commentTimeStamp,String commentProfilePic){
super();
this.commentId = commentId;
this.username = username;
this.commentBody = commentBody;
this.commentProfilePic= commentTimeStamp;
this.commentTimeStamp= commentProfilePic;
}
public int getCommentId() {
return commentId;
}
public void setCommentId(int commentId) {
this.commentId = commentId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getCommentBody() {
return commentBody;
}
public void setCommentBody(String commentBody) {
this.commentBody = commentBody;
}
public String getCommentTimeStamp() {
return commentTimeStamp;
}
public void setCommentTimeStamp(String commentTimeStamp) {
this.commentTimeStamp = commentTimeStamp;
}
public String getCommentProfilePic() {
return commentProfilePic;
}
public void setCommentProfilePic(String commentProfilePic) {
this.commentProfilePic = commentProfilePic;
}
}

First of all try to print out your dataSet size into getItemCount method of recyclerview -
#Override
public int getItemCount() {
Log.e("Size of data:", "" +commentItems.size())
return commentItems.size();
}
If it returns greater than zero - there may be a problem with your row_item of recyclerview. Double check your comment_item.xml file. Possibly try to remove weights.

Are items not showing in the cards or is the recycler view itself not showing?
If the recycler view itself is not showing, maybe the problem is inside the getItemCount the size being sent is 0.
do a check there and return 1 if size is zero.
#Override
public int getItemCount() {
if(commentItems.size() == 0)
return 1;
else
return commentItems.size();
}

Related

Can't set RecyclerView inside CardView?

I'm trying to put a RecyclerView inside a CardView and create items dynamically.
Obviously, in XML, RecyclerView is set inside CardView tag, but as you can see picture, RecyclerView item is created outside CardView.
(RecyclerView's items are the parts expressed as kg and set in the photo. And CardView is also an item of another RecyclerView.)
What's the problem?
XML
<androidx.cardview.widget.CardView
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"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="12dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
app:cardElevation="10dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/ll1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/workout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="TEST"/>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#color/light_blue_400"/>
</LinearLayout>
<LinearLayout
android:id="#+id/ll2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="#+id/ll1">
<com.google.android.material.button.MaterialButton
android:id="#+id/delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:layout_marginEnd="4dp"
style="#style/RoutineButtonStyle"
android:text="DELETE"
app:icon="#drawable/ic_delete"/>
<com.google.android.material.button.MaterialButton
android:id="#+id/add"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="4dp"
android:layout_marginEnd="8dp"
style="#style/RoutineButtonStyle"
android:text="ADD"
app:icon="#drawable/ic_add"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/ll2"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
Let me know if you need any other code.
Here is the Activity of your add/delete CardView:
//Item List if you want to add one or more Items
private List<MyItem> myItems = new ArrayList<>();
private Adapter smallCardAdapter;
private int size;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.rv);
//Creates a new Object in the Adapter.class
smallCardAdapter = new Adapter();
recyclerView.setAdapter(smallCardAdapter);
CardView cardView = findViewById(R.id.cardView);
MaterialButton delete = findViewById(R.id.delete);
MaterialButton add = findViewById(R.id.add);
//Add onClickListener
add.setOnClickListener(v -> {
try {
size = myItems.size();
//if the value is 0, a new item is created
//if you want to delete the card after 0 than you have to change the value to 0
if(size == 0){
//Creates a new Object in the MyItem.class
myItems.add(new MyItem("Set","1kg"));
}else{
MyItem myItem = myItems.get(0);
//Replace kg with "" to make a Integer
String secondString = myItem.getSecondString().replace("kg","");
Integer value = Integer.valueOf(secondString);
value++;
myItem.setSecondString(value+"kg");
myItems.set(0,myItem);
}
updateAdapter();
}catch (Exception e){
Log.w("MainActivity","Add Button OnClickListener");
e.printStackTrace();
}
});
//Delete onClickListener
delete.setOnClickListener(v->{
try {
size = myItems.size();
//If the value is 0 then canceled to avoid errors
if(size == 0){
return;
}
MyItem myItem = myItems.get(0);
//Replace kg with "" to make a Integer
String secondString = myItem.getSecondString().replace("kg","");
Integer value = Integer.valueOf(secondString);
//if the value is one or lower
if(value <= 1){
//The card will deleted after updateAdapter();
myItems.clear();
}else{
value--;
myItem.setSecondString(value+"kg");
myItems.set(0,myItem);
}
updateAdapter();
}catch (Exception e){
Log.w("MainActivity","Delete Button OnClickListener");
e.printStackTrace();
}
});
}
private void updateAdapter(){
try {
smallCardAdapter.setItems(myItems);
}catch (Exception e){
Log.w("MainActivity","updateAdapter");
e.printStackTrace();
}
}
The custom Item called MyItem:
public class MyItem {
String firstString;
String secondString;
public MyItem(String firstString,String secondString){
this.firstString = firstString;
this.secondString = secondString;
}
public String getFirstString() {
return firstString;
}
public void setFirstString(String firstString) {
this.firstString = firstString;
}
public String getSecondString() {
return secondString;
}
public void setSecondString(String secondString) {
this.secondString = secondString;
}
}
The Adapter.java creates a smallCard:
public class Adapter extends RecyclerView.Adapter<Adapter.SmallCardHolder> {
private List<MyItem> items = new ArrayList<>();
#NonNull
#Override
public SmallCardHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
// I created a new smallcard for the CardView
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.smallcard, parent, false);
SmallCardHolder smallCardHolder = new SmallCardHolder(itemView);
return smallCardHolder;
}
#Override
public void onBindViewHolder(#NonNull final SmallCardHolder holder, int position) {
//get the current item of the position
MyItem myItem = items.get(position);
String firstString = myItem.getFirstString();
String secondString = myItem.getSecondString();
holder.textViewSet.setText(firstString);
holder.textViewkg.setText(secondString);
}
#Override
public int getItemCount () {
return items.size();
}
public void setItems(List <MyItem> items) {
this.items = items;
notifyDataSetChanged();
}
class SmallCardHolder extends RecyclerView.ViewHolder {
//Here are the TextView's of the smallcard (smallcard.xml)
private TextView textViewSet;
private TextView textViewkg;
public SmallCardHolder(#NonNull View itemView) {
super(itemView);
textViewSet = itemView.findViewById(R.id.set);
textViewkg = itemView.findViewById(R.id.kg);
}
}
}
Create a new layout with name called smallcard.xml for the Adapter.java:
<?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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/set"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Set"
android:layout_centerVertical="true"
android:textSize="18sp"
android:layout_marginStart="5dp"
android:textColor="?attr/colorPrimary"
android:textStyle="bold"/>
<TextView
android:id="#+id/kg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="kg"
android:layout_toRightOf="#id/set"
android:layout_marginLeft="55dp"
android:layout_centerVertical="true"
android:textColor="?attr/colorPrimary"
android:textSize="16sp"
android:layout_marginRight="10dp"
android:maxLines="1"/>
</RelativeLayout>
</RelativeLayout>
In your XML you have to give the CardView a name. I called it cardView. Here is the code android:id="#+id/cardView"
Result:
You will find more information as comments in the code.

Bug in recycle grid. Changing UI without click randomly

I have a recycler inside fragment in view pager.
The problem that it put likes on user accounts in UI randomly but in DB everything is fine.
In logs, I see that random is not influence on BD. So the bug is only in UI part. After the refresh of the list, it can appear again and after that disappear.
I would like to share code but I already don't have an I idea where the problem could be. It might be in adapter/refresh list listener / XML or any other places. Please let me know what part of the code you need and I will provide it. Maybe it is a bug of recycler as itself and I can't fix it.
Adapter class code:
public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.UserViewHolder>{
private List<FsUser> fsUserList = new ArrayList<>();
private OnItemClickListener.OnItemClickCallback onItemClickCallback;
private OnItemClickListener.OnItemClickCallback onChatClickCallback;
private OnItemClickListener.OnItemClickCallback onLikeClickCallback;
private Context context;
public SearchAdapter(OnItemClickListener.OnItemClickCallback onItemClickCallback,
OnItemClickListener.OnItemClickCallback onChatClickCallback,
OnItemClickListener.OnItemClickCallback onLikeClickCallback) {
this.onItemClickCallback = onItemClickCallback;
this.onChatClickCallback = onChatClickCallback;
this.onLikeClickCallback = onLikeClickCallback;
}
public void addUsers(List<FsUser> userList) {
fsUserList.addAll(userList);
notifyItemRangeInserted(fsUserList.size() - userList.size(), fsUserList.size());
}
public void clearData(){
fsUserList.clear();
notifyDataSetChanged();
}
#NonNull
#Override
public UserViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user, parent, false);
return new UserViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull UserViewHolder holder, int position) {
FsUser fsUser = fsUserList.get(position);
holder.bind(fsUser, position);
}
#Override
public int getItemCount() {
return fsUserList.size();
}
public String getLastItemId(){
return fsUserList.get(fsUserList.size() - 1).getUid();
}
class UserViewHolder extends RecyclerView.ViewHolder {
RelativeLayout container;
ImageView imageView, like, chat;
TextView name, country;
private LottieAnimationView animationView;
UserViewHolder(View itemView) {
super(itemView);
context = itemView.getContext();
container = itemView.findViewById(R.id.item_user_container);
imageView = itemView.findViewById(R.id.user_img);
like = itemView.findViewById(R.id.search_btn_like);
chat = itemView.findViewById(R.id.search_btn_chat);
name = itemView.findViewById(R.id.user_name);
country = itemView.findViewById(R.id.user_country);
animationView = itemView.findViewById(R.id.lottieAnimationView);
}
void bind(FsUser fsUser, int position){
ViewCompat.setTransitionName(imageView, fsUser.getName());
if (FirebaseUtils.isUserExist() && fsUser.getUid() != null) {
new FriendRepository().isLiked(fsUser.getUid(), flag -> {
if (flag) {
like.setBackground(ContextCompat.getDrawable(context, R.drawable.ic_favorite));
animationView.setVisibility(View.VISIBLE);
}
});
}
if(fsUser.getUid() != null) {
chat.setOnClickListener(new OnItemClickListener(position, onChatClickCallback));
like.setOnClickListener(new OnItemClickListener(position, onLikeClickCallback));
}
imageView.setOnClickListener(new OnItemClickListener(position, onItemClickCallback));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
if(fsUser.getImage().equals("default")){
Glide.with(context).load(context.getResources().getDrawable(R.drawable.default_avatar)).into(imageView);
} else {
Glide.with(context).load(fsUser.getImage()).thumbnail(0.5f).into(imageView);
}
name.setText(fsUser.getName());
country.setText(fsUser.getCountry());
ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f).setDuration(500);
animator.addUpdateListener(valueAnimator ->
animationView.setProgress((Float) valueAnimator.getAnimatedValue()));
if (animationView.getProgress() == 0f) {
animator.start();
} else {
animationView.setProgress(0f);
}
}
}
}
And xml file of RecyclerView item:
<?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"
android:id="#+id/item_user_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="#dimen/user_cv_width"
android:layout_height="#dimen/user_cv_height"
android:layout_margin="#dimen/dp4"
android:elevation="#dimen/dp4">
<RelativeLayout
android:id="#+id/item_user_main_relative_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/item_user_top_relative_container"
android:layout_width="#dimen/user_rl_width"
android:layout_height="#dimen/user_rl_height">
<ImageView
android:id="#+id/user_img"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="#drawable/default_avatar" />
<RelativeLayout
android:id="#+id/item_user_top_relative"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/user_item_bg"
android:orientation="vertical">
<TextView
android:id="#+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/dp4"
android:textColor="#android:color/white"
android:textSize="#dimen/medium_text_size" />
<TextView
android:id="#+id/user_country"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:layout_marginStart="#dimen/dp4"
android:textSize="#dimen/medium_text_size" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="#+id/item_user_bottom_relative_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/dp12">
<ImageView
android:id="#+id/search_btn_like"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/heart_outline"
android:contentDescription="#string/search_btn_like_desc"/>
<com.airbnb.lottie.LottieAnimationView
android:id="#+id/lottieAnimationView"
android:visibility="gone"
android:layout_width="#dimen/lottie_animation_view_size"
android:layout_height="#dimen/lottie_animation_view_size"
app:lottie_loop="true"
app:lottie_autoPlay="true"
app:lottie_fileName="like.json"/>
</RelativeLayout>
<ImageView
android:id="#+id/search_btn_chat"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="#dimen/dp12"
android:layout_weight="1"
android:src="#drawable/message_outline" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
Override this two methods inside your adapter
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}

onBindViewHolder not called after RecyclerView Adapter notifyDataSetChanged()

I'm getting some data from Firebase database and I'm trying to populate RecyclerView adapter with it. After Adapter's notifyDataSetChanged() is called, screen blinks and nothing happens, I couldn't even catch a breakpoint inside onBindViewHolder.
Here is my code:
POJO class:
public class Result2 implements Serializable {
private int score;
private String userName;
public Result2(int score, String userName) {
this.score = score;
this.userName = userName;
}
public int getScore() {
return score;
}
public String getUserName() {
return userName;
}
}
This is my activitys layout called activity_results.xml that contains RecyclerView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:weightSum="2">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="USERNAME"
android:textColor="#000"
android:textSize="16sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="SCORE"
android:textColor="#000"
android:textSize="16sp"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000"
/>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingTop="10dp"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
Here is my Adapters ViewHolder layout called score_view_holder.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:weightSum="2">
<TextView
android:id="#+id/username"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:textSize="14sp"/>
<TextView
android:id="#+id/score"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:textSize="14sp"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:background="#4545"/>
So it will contain two horizontal TextViews and a View as a line below..
Here is my Adapter:
public class ScoreAdapter extends RecyclerView.Adapter<ScoreAdapter.ScoreViewHolder> {
private List<Result2> results = new ArrayList<>();
public void setResults(List<Result2> results) {
this.results.clear();
this.results.addAll(results);
notifyDataSetChanged();
}
#Override
public ScoreAdapter.ScoreViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.score_view_holder, parent, false);
return new ScoreAdapter.ScoreViewHolder(view);
}
#Override
public void onBindViewHolder(ScoreAdapter.ScoreViewHolder holder, int position) {
Result2 result = getResult(position);
if (result != null) {
holder.setUsername(result.getUserName() != null ? result.getUserName() : "-");
holder.setScore(String.valueOf(result.getScore()));
}
}
private Result2 getResult(int position) {
return !results.isEmpty() ? results.get(position) : null;
}
#Override
public int getItemCount() {
return results.size();
}
public class ScoreViewHolder extends RecyclerView.ViewHolder {
private TextView username;
private TextView score;
public ScoreViewHolder(View itemView) {
super(itemView);
username = itemView.findViewById(R.id.username);
score = itemView.findViewById(R.id.score);
}
public void setUsername(String username) {
this.username.setText(username);
}
public void setScore(String score) {
this.score.setText(score);
}
}
}
It should get List of Result2 objects and just set text in those two TextViews (username and score)
And finally my Activity where I'm trying to notify adapter from:
public class Results extends AppCompatActivity {
private DatabaseReference mDatabase;
private ScoreAdapter scoreAdapter;
private RecyclerView recyclerView;
private List<Result2> results = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_results);
recyclerView = findViewById(R.id.recycler_view);
scoreAdapter = new ScoreAdapter();
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(scoreAdapter);
mDatabase = FirebaseDatabase.getInstance().getReference();
loadResults();
}
private void loadResults() {
mDatabase.child("Users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
Result2 result = childSnapshot.getValue(Result2.class);
if (result != null) {
results.add(result);
}
}
Toast.makeText(Results.this, String.valueOf(results.size()), Toast.LENGTH_SHORT).show();
scoreAdapter.setResults(results);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
}
);
}
}
So after for loop is done, Toast shows correct number of results, adapter setResults method is called, there i receive correct number of results, here is a picture:
But after notifyDataSetChanged() is called, screen just blinks and everything is blank... methods inside onBindViewHolder can not be reached after putting breakpoints on them.. Any idea what's wrong here?
There are several problems in your code. The first one is that you are calling the setResults() method and pass your results list inside your ScoreAdapter class and not to the constrcutor. In order to solve this, change your setResults() method to become a constructor like this:
public ScoreAdapter(List<Result2> results) {
this.results.clear();
this.results.addAll(results);
notifyDataSetChanged();
}
The adapter must also be instantiated and set to your RecyclerView inside the callback. So to solve this, simply move the following lines of code:
ScoreAdapter scoreAdapter = new ScoreAdapter(result);
recyclerView.setAdapter(scoreAdapter);
Right after the following line:
Toast.makeText(Results.this, String.valueOf(results.size()), Toast.LENGTH_SHORT).show();
Don't also forget to comment this line of code: scoreAdapter.setResults(results);.
See now, to instantiate the adapter you need to pass the result list to the constructor.
Also please also don't forget to add the public no-argument constructor to your Result2 class. Please see here more details.

How to properly implement a nested recyclerview, child recyclerviews behaving oddly

I am developing a chat application. The chat messages consists of normal text messages and sometimes it can be a list of items in a recyclerview.
So I've implemented nested Recyclerview. So what happens is in the json response if the message is just a normal text is a textview will be displayed but the message contains a URL then the horizantal recyclerview is shown in place of textview.
The problem is if in the json reponse let's say there are 10 messages and in that 10, 4 of them are URL's so i should be seeing 6 normal texts and 4 Recyclerviews. But the nested recyclerview is behaving very oddly sometimes it doesn't even display, sometimes i can see 2 Recyclerviews and sometimes 4 of them but with the same URL (same list of items).
I don't what i am doing wrong. can someone take a look at the code and tell me what's wrong?
My Parent(Vertical) Recyclerview layout
<layout 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">
<data>
<variable
name="messageViewModel"
type="com.sukshi.sukshichat.viewmodel.MessageFragmViewModel"/>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.fragment.MessagesFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_message"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:background="#ffffff"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:layout_marginTop="0dp"
android:layout_below="#+id/kjk"
android:layout_above="#+id/rv_message_container"
tools:listitem="#layout/test"
/>
</RelativeLayout>
</layout>
Vertical Recyclerview child layout
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<import
alias="cons"
type="com.sukshi.sukshichat.utils.ConstantsFirebase"/>
<import type="android.view.View"/>
<variable
name="messageViewModel"
type="com.sukshi.sukshichat.viewmodel.MessageAdapterViewModel"/>
</data>
<android.support.percent.PercentRelativeLayout
android:layout_height="wrap_content"
android:id="#+id/rv_container"
android:layout_width="wrap_content">
<android.support.v7.widget.RecyclerView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="10dp"
android:id="#+id/nested_recyclerview"
>
</android.support.v7.widget.RecyclerView>
<RelativeLayout
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="4dp"
android:id="#+id/sender"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="4dp"
app:layout_widthPercent="70%">
<hani.momanii.supernova_emoji_library.Helper.EmojiconTextView
android:layout_height="wrap_content"
android:id="#+id/tv_item_message"
android:layout_width="wrap_content"
android:maxWidth="300dp"
android:textColor="#ffffff"
android:text="#{messageViewModel.message}"
android:background="#drawable/chat_sender"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:padding="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{messageViewModel.time}"
android:layout_marginRight="4dp"
android:id="#+id/tv_item_message_time"
android:layout_alignBottom="#+id/tv_item_message"
android:layout_toLeftOf="#+id/tv_item_message"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/iv_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:maxHeight="#dimen/item_message_max_height"
android:maxWidth="#dimen/item_message_max_width"
android:onClick="#{messageViewModel::onItemClick}"
android:scaleType="centerCrop"
android:transitionName="shared"
android:visibility="#{messageViewModel.typeMessage ? View.GONE : View.VISIBLE}"
app:mapLocation="#{messageViewModel.mapLocation}"
app:photoUrlMessage="#{messageViewModel.message}"/>
</FrameLayout>
</RelativeLayout>
<RelativeLayout
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="4dp"
android:id="#+id/reciever"
android:layout_marginBottom="4dp"
app:layout_widthPercent="70%">
<hani.momanii.supernova_emoji_library.Helper.EmojiconTextView
android:layout_height="wrap_content"
android:id="#+id/tv_item_message1"
android:layout_width="wrap_content"
android:background="#drawable/chat_recieve"
android:maxWidth="300dp"
android:textColor="#000000"
android:text="#{messageViewModel.message}"
android:padding="10dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/show_garments2"
android:text="Show Garments"
android:visibility="gone"
android:background="#drawable/chat_recieve"
android:elevation="10dp"
android:paddingLeft="10dp"
android:textColor="#000000"
style="#style/Widget.AppCompat.Button.Colored"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{messageViewModel.time}"
android:id="#+id/tv_item_message_time11"
android:layout_marginLeft="4dp"
android:layout_alignBottom="#+id/tv_item_message1"
android:layout_toRightOf="#+id/tv_item_message1"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/iv_image1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:maxHeight="#dimen/item_message_max_height"
android:maxWidth="#dimen/item_message_max_width"
android:onClick="#{messageViewModel::onItemClick}"
android:scaleType="centerCrop"
android:transitionName="shared"
android:visibility="#{messageViewModel.typeMessage ? View.GONE : View.VISIBLE}"
app:mapLocation="#{messageViewModel.mapLocation}"
app:photoUrlMessage="#{messageViewModel.message}"/>
</FrameLayout>
</RelativeLayout>
</android.support.percent.PercentRelativeLayout>
</layout>
Vertical Recyclerview adapter
private void initializeFirebase() {
if (valueUserListener == null) {
valueUserListener = createFirebaseUsersListeners();
}
mRefUsers = FirebaseDatabase.getInstance().getReference(ConstantsFirebase.FIREBASE_LOCATION_USERS);
mRefUsers.keepSynced(true);
mRefUsers.addValueEventListener(valueUserListener);
Query messagesRef = FirebaseDatabase.getInstance()
.getReference(ConstantsFirebase.FIREBASE_LOCATION_CHAT)
.child(mChildChatKey)
.orderByKey().limitToLast(50);
messagesRef.keepSynced(true);
attachMessagesToRecyclerView(messagesRef);
}
private void attachMessagesToRecyclerView(final Query messagesReference) {
mAdapter = new FirebaseRecyclerAdapter<Message, MessageItemHolder>(Message.class,
R.layout.test123, MessageItemHolder.class, messagesReference) {
#Override
public MessageItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Test123Binding adapterItemMessageBinding = DataBindingUtil.inflate(LayoutInflater
.from(parent.getContext()), viewType, parent, false);
return new MessageItemHolder(adapterItemMessageBinding);
}
#Override
protected void populateViewHolder(final MessageItemHolder viewHolder, final Message message, int position) {
int index = mUsersEmails.indexOf(message.getEmail());
if (index != -1) {
viewHolder.bindMessage(mUsers.get(index), message, MessagesFragment.this);
}
if (viewHolder.mAdapterItemMessageBinding.getMessageViewModel().isSender()){
viewHolder.mAdapterItemMessageBinding.reciever.setVisibility(View.GONE);
viewHolder.mAdapterItemMessageBinding.sender.setVisibility(View.VISIBLE);
}else {
viewHolder.mAdapterItemMessageBinding.reciever.setVisibility(View.VISIBLE);
viewHolder.mAdapterItemMessageBinding.sender.setVisibility(View.GONE);
}
String http = message.getMessage();
// if (htttpmessage != null){
if (http.contains("google") && message.getType() == 0){
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setLayoutParams(params);
filterLink = message.getMessage();
ListOfdataAdapter.clear();
JSON_HTTP_CALL(filterLink);
nestedRecyclerview(viewHolder);
viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setVisibility(View.VISIBLE);
viewHolder.mAdapterItemMessageBinding.tvItemMessage1.setVisibility(View.INVISIBLE);
// filterLink = message.getFilterLink();
}else{
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(0,
0);
viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setLayoutParams(params);
viewHolder.bindMessage(mUsers.get(index), message, MessagesFragment.this);
viewHolder.mAdapterItemMessageBinding.tvItemMessage1.setVisibility(View.VISIBLE);
}
if (message.getType() == 1 || message.getType() == 2){
viewHolder.mAdapterItemMessageBinding.tvItemMessage.setVisibility(View.INVISIBLE);
}else {
viewHolder.mAdapterItemMessageBinding.tvItemMessage.setVisibility(View.VISIBLE);
}
/* viewHolder.mAdapterItemMessageBinding.showGarments2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showpDialog();
filterLink = message.getMessage();
ListOfdataAdapter.clear();
JSON_HTTP_CALL(filterLink);
}
});
*/
}
};
mFragmentMessagesBinding.rvMessage.setAdapter(mAdapter);
mFragmentMessagesBinding.rvMessage.getAdapter().registerAdapterDataObserver(
new RecyclerView.AdapterDataObserver() {
#Override public void onItemRangeInserted(int position, int itemCount) {
super.onItemRangeInserted(position, itemCount);
mFragmentMessagesBinding.rvMessage.scrollToPosition(position);
}
});
}
So whenever there is a URl in the message key below method will be called
public void JSON_HTTP_CALL(String url){
RequestOfJSonArray = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
ParseJSonResponse(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue = Volley.newRequestQueue(getActivity());
requestQueue.add(RequestOfJSonArray);
}
public void ParseJSonResponse(JSONArray array){
for(int i = 0; i<array.length(); i++) {
UploadImage GetDataAdapter2 = new UploadImage();
JSONObject json = null;
try {
hidepDialog();
json = array.getJSONObject(i);
GetDataAdapter2.setBrand_name(json.getString(Image_Name_JSON));
// Adding image title name in array to display on RecyclerView click event.
ImageTitleNameArrayListForClick.add(json.getString(Image_Name_JSON));
GetDataAdapter2.setImage(json.getString(Image_URL_JSON));
GetDataAdapter2.setGarment_price(json.getString(garment_price));
GetDataAdapter2.setGarment_name(json.getString(garment_name));
GetDataAdapter2.setImage_full(json.getString(image_full));
GetDataAdapter2.setDesc_text(json.getString(desc_text));
} catch (JSONException e) {
e.printStackTrace();
}
ListOfdataAdapter.add(GetDataAdapter2);
// showFragment();
}
}
Horizantal Recyclerview adapter
final WrapContentLinearLayoutManager linearLayoutManager = new WrapContentLinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(WrapContentLinearLayoutManager.HORIZONTAL);
viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setLayoutManager(linearLayoutManager);
viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setHasFixedSize(true);
//mFragmentMessagesBinding.recyclerview1.addItemDecoration(new PaddingItemDecoration(size));
viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setItemAnimator(new DefaultItemAnimator());
DialogRecyclerViewAdapter rvAdapter = new DialogRecyclerViewAdapter(ListOfdataAdapter, getActivity());
viewHolder.mAdapterItemMessageBinding.nestedRecyclerview.setAdapter(rvAdapter);
rvAdapter.notifyDataSetChanged();
Horizantal Recyclerview Adapter
public class DialogRecyclerViewAdapter extends RecyclerView.Adapter<DialogRecyclerViewAdapter.ViewHolder> {
Context context;
List<UploadImage> dataAdapters;
private SharedPreferences.Editor mSharedPrefEditor;
ImageLoader imageLoader;
public DialogRecyclerViewAdapter(List<UploadImage> getDataAdapter, Context context){
super();
this.dataAdapters = getDataAdapter;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder Viewholder, int position) {
final UploadImage dataAdapterOBJ = dataAdapters.get(position);
imageLoader = ImageAdapter.getInstance(context).getImageLoader();
imageLoader.get(dataAdapterOBJ.getImage(),
ImageLoader.getImageListener(
Viewholder.VollyImageView,//Server Image
R.drawable.loading_1,//Before loading server image the default showing image.
android.R.drawable.ic_dialog_alert //Error image if requested image dose not found on server.
)
);
}
#Override
public int getItemCount() {
return dataAdapters.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
public TextView ImageTitleTextView, garment_price, size;
public NetworkImageView VollyImageView ;
public ViewHolder(View itemView) {
super(itemView);
VollyImageView = (NetworkImageView) itemView.findViewById(R.id.VolleyImageView) ;
}
}
}
Vertical Recyclerview ViewHolder
public static class MessageItemHolder extends RecyclerView.ViewHolder {
private Test123Binding mAdapterItemMessageBinding;
public MessageItemHolder(Test123Binding adapterItemMessageBinding) {
super(adapterItemMessageBinding.rvContainer);
mAdapterItemMessageBinding = adapterItemMessageBinding;
}
public void bindMessage(User user, Message message, MessageAdapterViewModelContract contract) {
if (mAdapterItemMessageBinding.getMessageViewModel() == null) {
mAdapterItemMessageBinding.setMessageViewModel(new MessageAdapterViewModel(user,
encodedMail, message, contract));
} else {
mAdapterItemMessageBinding.getMessageViewModel().setUser(user);
mAdapterItemMessageBinding.getMessageViewModel().setMessage(message);
}
}
}

ListView leaves extra space below and above of the list

I have dynamic list of several name. But ListView leaves extra space below and above of the total list item.
At routes_recycler_listview.xml, Here, I have use this:
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center_vertical"
android:paddingEnd="0dp"
android:paddingStart="10dp"
android:textColor="#color/md_black_1000"
android:textSize="20sp" />
</RelativeLayout>
<com.github.aakira.expandablelayout.ExpandableRelativeLayout
android:id="#+id/expandableLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/header"
android:background="#drawable/recycler_item_bg"
app:ael_duration="400"
app:ael_expanded="true"
app:ael_orientation="vertical">
<ListView
android:id="#+id/lv_routes_assigned"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#color/fontColor"
android:textSize="16sp" />
</com.github.aakira.expandablelayout.ExpandableRelativeLayout>
</RelativeLayout>
But, i got this ,
Edit
After removing android:layout_centerInParent="true" :
In my RecyclerViewRecyclerAdapter class, i use following:
At ViewHolder class :
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public ListView routesAssign;
public ExpandableRelativeLayout expandableLayout;
public ViewHolder(View v) {
super(v);
textView = (TextView) v.findViewById(R.id.textView);
routesAssign = (ListView) v.findViewById(R.id.lv_routes_assigned);
expandableLayout = (ExpandableRelativeLayout) v.findViewById(R.id.expandableLayout);
}
}
At onBindViewHolder method:
holder.textView.setText(item.getDateString());
CustomAdapter testAdapter = new CustomAdapter(context, item.getRoutes());
holder.routesAssign.setAdapter(testAdapter);
holder.routesAssign.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
Intent i = new Intent(context, RoutesShapesActivity.class);
Log.e("id - onItemClick", item.getRoutes().get(pos).getId() + "-- Test --");
i.putExtra("route_id", item.getRoutes().get(pos).getId());
i.putExtra("assigned_id", item.getRoutes().get(pos).getAssignId());
i.putExtra("update", item.getRoutes().get(pos).getIsUpdated());
context.startActivity(i);
}
});
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
item.getRoutes().size() * 200);
p.addRule(RelativeLayout.BELOW, R.id.header);
p.addRule(RelativeLayout.CENTER_IN_PARENT, R.id.header);
holder.expandableLayout.setLayoutParams(p);
holder.expandableLayout.setInterpolator(Utils.createInterpolator(Utils.DECELERATE_INTERPOLATOR));
holder.expandableLayout.setExpanded(true);
At onCreateViewHolder method :
#Override
public ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
this.context = parent.getContext();
return new ViewHolder(LayoutInflater.from(context)
.inflate(R.layout.routes_recycler_listview, parent, false));
}
In my CustomAdapter class:
At getItem method :
#Override
public Routes getItem(int position) {
return data.get(position);
}
At getView method :
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Routes route = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = inflater.inflate(R.layout.route_assigned_list, parent, false);
}
// Lookup view for data population
TextView tvName = (TextView) convertView.findViewById(R.id.route_assign_text_view);
ImageView imageView = (ImageView) convertView.findViewById(R.id.route_assign_pause_state);
Log.e("Test --- ", route.getRouteName());
tvName.setText(route.getRouteName());
return convertView;
}
My getter and setter method in Routes class. Here,
public class Routes {
//
// "assignId": 22,
// "routeId": 15,
// "routeName": "NY-CLSTR23",
// "createdDate": "2016-04-15 09:51:45"
#SerializedName("assignId")
private int assignId;
#SerializedName("assignDate")
private String assignDate;
#SerializedName("routeId")
private int id;
#SerializedName("routeName")
private String routeName;
#SerializedName("createdDate")
private String createdDate;
#SerializedName("isUpdated")
private String isUpdated;
/*"assignId": 167,
"assignDate": "2016-06-17",
"routeId": 137,
"routeName": "Test June 16",
"createdDate": "2016-06-16 00:14:27",
"isUpdated": "true"*/
public int getAssignId() {
return assignId;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRouteName() {
return routeName;
}
public void setRouteName(String routeName) {
this.routeName = routeName;
}
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
public void setAssignId(int assignId) {
this.assignId = assignId;
}
public String getAssignDate() {
return assignDate;
}
public void setAssignDate(String assignDate) {
this.assignDate = assignDate;
}
public String getIsUpdated() {
return isUpdated;
}
public void setIsUpdated(String isUpdated) {
this.isUpdated = isUpdated;
}
}
I have really hard time here. So, what can be done to remove that space from the the listview ?
This is not done by ListView, this is done by the custom relative layout and tag which which you are using with ListView android:layout_centerInParent="true"
<ListView
android:id="#+id/lv_routes_assigned"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#color/fontColor"
android:textSize="16sp" />
So remove this attribute from ListView which will solve your problem.
<ListView
android:id="#+id/lv_routes_assigned"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/fontColor"
android:textSize="16sp" />
You can use android:layout_alignParentTop="true" attribute into your ListView also.
you should add a background color (eg. #F00) to see if the problem is with listview or with its container.
after that i will use this in listview
android:fillViewport="true"
not sure so just give it a try
you have android:layout_centerInParent="true" defined in your listview which is causing this, try removing that
<com.github.aakira.expandablelayout.ExpandableRelativeLayout
android:id="#+id/expandableLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="0dp" // this is just in case if your customview is setting some minheight
android:layout_below="#id/header"
android:background="#drawable/recycler_item_bg"
app:ael_duration="400"
app:ael_expanded="true"
app:ael_orientation="vertical">
<ListView
android:id="#+id/lv_routes_assigned"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/fontColor"
android:textSize="16sp" />
</com.github.aakira.expandablelayout.ExpandableRelativeLayout>

Categories

Resources