I have 4 CardViews in a Activity and each CardView has a RecyclerView. Each RecyclerView has around 8-10 rows/item. Scrolling of this page/activity is very slow.
I suspect some problem in my RecyclerView.Adapter class.
Can somebody please let me know what could be the issue in my code?
Adapter:
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
public class JyotishAppAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<DataModel> dataList;
private int cardView;
public static final int CARD_2_COL = 0;
public static final int CARD_3_COL_HEAD = 1;
public static final int CARD_2_COL2 = 2;
public static class GenericViewHolder extends RecyclerView.ViewHolder {
TextView itemName;
TextView itemDescription;
public GenericViewHolder (View itemView) {
super (itemView);
this.itemName = (TextView) itemView.findViewById(R.id.item_name);
this.itemDescription = (TextView) itemView.findViewById(R.id.item_description);
}
}
public static class GenericViewHolder2 extends RecyclerView.ViewHolder {
TextView itemName;
TextView itemDescription;
TextView itemStatus;
public GenericViewHolder2 (View itemView) {
super (itemView);
this.itemName = (TextView) itemView.findViewById(R.id.item_name);
this.itemDescription = (TextView) itemView.findViewById(R.id.item_description);
this.itemStatus = (TextView) itemView.findViewById(R.id.item_status);
}
}
public JyotishAppAdapter(ArrayList<DataModel> dataList, int cardView) {
this.dataList = dataList;
this.cardView = cardView;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v;
if (cardView == CARD_2_COL) {
v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.list_item, viewGroup, false);
return new GenericViewHolder(v);
} else if (cardView == CARD_2_COL2) {
v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.list_item3, viewGroup, false);
return new GenericViewHolder(v);
} else {
v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.list_item2, viewGroup, false);
return new GenericViewHolder2(v);
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, final int position) {
final DataModel dataModel = dataList.get(position);
if (viewHolder instanceof GenericViewHolder) {
GenericViewHolder holder = (GenericViewHolder) viewHolder;
holder.itemName.setText(Html.fromHtml(dataModel.getValue1()));
holder.itemDescription.setText(Html.fromHtml(dataModel.getValue2()));
if (dataModel.getValue4() != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Utility.showAlertMessage(view.getContext(), R.string.message_title,
Html.fromHtml(dataModel.getValue4()).toString());
}
});
}
} else {
GenericViewHolder2 holder = (GenericViewHolder2) viewHolder;
holder.itemName.setText(Html.fromHtml(dataModel.getValue1()));
holder.itemDescription.setText(Html.fromHtml(dataModel.getValue2()));
holder.itemStatus.setText(Html.fromHtml(dataModel.getValue3()));
if (dataModel.getValue4() != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Utility.showAlertMessage(view.getContext(), R.string.message_title,
Html.fromHtml(dataModel.getValue4()).toString());
}
});
}
}
}
#Override
public int getItemCount() {
return dataList.size();
}
}
Activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/PageContentBackground"
tools:context=".PanchangaActivity">
<include android:id="#+id/tool_bar"
layout="#layout/tool_bar" />
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tool_bar"
android:orientation="vertical"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:background="#color/PageContentBackground">
<TextView android:id="#+id/muhurta_zone"
style="#style/TextStyle"
android:textSize="#dimen/text_size_horo_data"
android:ellipsize="none"
android:scrollHorizontally="false"
android:layout_marginBottom="5dp"/>
<TextView android:id="#+id/muhurta_place"
style="#style/TextStyle"
android:textSize="#dimen/text_size_horo_data"
android:ellipsize="none"
android:scrollHorizontally="false"
android:layout_marginBottom="10dp"/>
<ScrollView android:layout_height="wrap_content"
android:layout_width="match_parent">
<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="#+id/cardview4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
card_view:cardElevation="5dp"
card_view:cardCornerRadius="5dp"
card_view:cardUseCompatPadding="true"
card_view:cardBackgroundColor="#color/CardViewColor">
<android.support.v7.widget.RecyclerView
android:id="#+id/panchanga_result_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/CardViewColor"
android:paddingLeft="3dp"
android:paddingRight="3dp" />
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id="#+id/cardview5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/cardview4"
android:layout_marginTop="10dp"
card_view:cardElevation="5dp"
card_view:cardCornerRadius="5dp"
card_view:cardUseCompatPadding="true"
card_view:cardBackgroundColor="#color/CardViewColor">
<android.support.v7.widget.RecyclerView
android:id="#+id/panchanga_result_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/CardViewColor"
android:paddingLeft="3dp"
android:paddingRight="3dp" />
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id="#+id/cardview6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/cardview5"
android:layout_marginTop="10dp"
card_view:cardElevation="5dp"
card_view:cardCornerRadius="5dp"
card_view:cardUseCompatPadding="true"
card_view:cardBackgroundColor="#color/CardViewColor">
<android.support.v7.widget.RecyclerView
android:id="#+id/panchanga_result_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/CardViewColor"
android:paddingLeft="3dp"
android:paddingRight="3dp" />
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id="#+id/cardview7"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/cardview6"
android:layout_marginTop="10dp"
card_view:cardElevation="5dp"
card_view:cardCornerRadius="5dp"
card_view:cardUseCompatPadding="true"
card_view:cardBackgroundColor="#color/CardViewColor">
<android.support.v7.widget.RecyclerView
android:id="#+id/panchanga_result_4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/CardViewColor"
android:paddingLeft="3dp"
android:paddingRight="3dp" />
</android.support.v7.widget.CardView>
</RelativeLayout>
</ScrollView>
</LinearLayout>
</RelativeLayout>
The problem is solved by setting setNestedScrollingEnabled to false.
recyclerView1.setNestedScrollingEnabled(false);
It is better to use NestedScrollView and set setNestedScrollingEnabled to false for better performance.
Related
I have recyclerview and it shows just single records instead of two records. I have searched many post on google and found to modify height of listview items from "match_parent " To "Wrap_Content" hence I did the same but still it shows single records.
Activity Mumbai_Male
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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=".MumbaiMale">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:layout_width="90dp"
android:layout_height="90dp"
android:id="#+id/myImg"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="20dp"
android:layout_marginLeft="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/name"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/age"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/education"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:scrollbars="vertical"
android:id="#+id/recyclerView" />
</LinearLayout>
CustomeAdapter is:
package com.maheshwaghela.mahesh.rukhivivah;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
public class CustomAdapter extends
RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private MumbaiMale.IconData[] data;
public CustomAdapter (MumbaiMale.IconData[] data) {
this.data = data;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View listItem= layoutInflater.inflate(R.layout.activity_mumbai_male, parent, false);
ViewHolder viewHolder = new ViewHolder(listItem);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.name.setText(data[position].getPname());
holder.age.setText(data[position].getPage());
holder.education.setText(data[position].getPedu());
holder.imageView.setImageResource(data[position].getImgId());
}
#Override
public int getItemCount() {
return data.length;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public TextView name;
public TextView age; public TextView education;
public ViewHolder(View itemView) {
super(itemView);
this.imageView = (ImageView) itemView.findViewById(R.id.myImg);
this.name = (TextView) itemView.findViewById(R.id.name);
this.age=(TextView) itemView.findViewById(R.id.age);
this.education=(TextView) itemView.findViewById(R.id.education);
}
}
}
Mumbai_Male.Java
package com.maheshwaghela.mahesh.rukhivivah;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
public class MumbaiMale extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mumbai_male);
IconData[] data = new IconData[] {
new IconData("Name:- Mahesh K. Waghela","Age:-45","Education:-B.com", R.drawable.dilip333),
new IconData ("Name:- Sunil K. Waghela","Age:-33","Education:-S.S.C.",R.drawable.hiteshhh)
};
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
CustomAdapter adapter=new CustomAdapter(data);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
public class IconData {
private String pname;
private String page;
private String pedu;
private int imgId;
public IconData(String name, String age, String edu, int imgId) {
this.pname = name;
this.page= age;
this.pedu= edu;
this.imgId = imgId;
}
public String getPname()
{
return pname;
}
public void setPname(String name)
{
this.pname = name;
}
public String getPage()
{
return page;
}
public void setPage(String age)
{
this.page=age;
}
public String getPedu()
{
return pedu;
}
public void setMyPedu(String edu)
{
this.pedu=edu;
}
public int getImgId()
{
return imgId;
}
public void setImgId(int imgId)
{
this.imgId = imgId;
}
}
}
Where I am wrong don't know but it shows single records instead of two records.
As per your current code, your RecyclerView will display both record for both wrap_content and match_parent. You can see second record if you will scroll your list.
Also You are getting this type of wired output because your are using the same layout as a Activity Layout and Adapter's item layout. So adapter will bind image, name etc.. but it will also display a blank RecyclerView for each row.
So the solution is just keep your RecyclerView inside activity_mumbai_male.xml and create new xml file for your RecyclerView item and inflate that layout xml file inside your adapter. Your issue will be fixed.
Please check below corrected code.
activity_mumbai_male.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MumbaiMale">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:scrollbars="vertical" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
item_list.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:orientation="horizontal">
<ImageView
android:id="#+id/myImg"
android:layout_width="90dp"
android:layout_height="90dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:orientation="vertical">
<TextView
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/age"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/education"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
Replace your code with my below code in CustomAdapter.xml
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View listItem = layoutInflater.inflate(R.layout.item_list, parent, false);
ViewHolder viewHolder = new ViewHolder(listItem);
return viewHolder;
}
You are using RecyclerView, but I could not found your xml regarding Row, you have set text to the Simple Single TextView Which you have provide in your activity_mumbai.xml, To you recyclerview you need to create another xml, which is counted as a row, means single item of your RecyclerView, and Print your xml data in that view.
row_item_view.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="90dp"
android:layout_height="90dp"
android:id="#+id/myImg"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="20dp"
android:layout_marginLeft="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/name"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/age"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/education"/>
</LinearLayout>
</LinearLayout>
and Change SetContentView in your custom adapter with this new xml.
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View listItem= layoutInflater.inflate(R.layout.row_item_view, parent, false);
ViewHolder viewHolder = new ViewHolder(listItem);
return viewHolder;
}
This will fix your problem.
I'm using Recyclerview in one of my activity, but I'm not able to show any data in recyclerView.
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#color/colorPrimary"
android:id="#+id/toolBar">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_back_light"
android:layout_gravity="center"
android:layout_marginStart="16dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sushi"
android:textColor="#color/white"
android:textStyle="bold"
android:layout_gravity="center"
android:layout_marginStart="12dp"
android:textSize="18sp"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/chatMessages"
android:clipToPadding="false"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:layout_below="#+id/toolBar"
android:layout_above="#+id/messageInputView"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:id="#+id/messageInputView">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:background="#D9D9D9"
android:id="#+id/border"
android:layout_alignParentTop="true"/>
<EditText
android:id="#+id/messageInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="#color/transparent"
android:layout_toLeftOf="#+id/messageSendButton"
android:hint="Type a message..."
android:textColorHint="#80282a2b"
android:inputType="textAutoCorrect|textAutoComplete|textMultiLine|textCapSentences"/>
<ImageView
android:id="#+id/messageSendButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="#drawable/ic_send"
android:onClick="onClick"
android:padding="4dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:background="#drawable/send_message_background"/>
</RelativeLayout>
</RelativeLayout>
All callback methods of RecyclerView.Adapter<RecyclerView.ViewHolder> not calling on calling notifydatasetchanged().
Adapter code here :
public class ChatMessagesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static String TAG = "ChatMessagesAdapter";
private ArrayList<ChatMessages> mChatMessages;
private Context mContext;
public ChatMessagesAdapter(ArrayList<ChatMessages> chatMessages, Context context){
mContext = context.getApplicationContext();
mChatMessages = chatMessages;
Log.d("ChatActivity Adapter", String.valueOf(mChatMessages.size()));
setHasStableIds(true);
}
public synchronized void refreshData(ArrayList<ChatMessages> feeds){
Log.d("ChatActivity Adapter", String.valueOf(feeds.size()));
mChatMessages.clear();
mChatMessages.addAll(feeds);
Log.d("ChatActivity Adapter", String.valueOf(mChatMessages.size()));
notifyDataSetChanged();
}
class IncomingMessageHolder extends RecyclerView.ViewHolder {
#BindView(R.id.messageText) TextView mMessageText;
#BindView(R.id.messageTime) TextView mMessageTime;
IncomingMessageHolder(View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
}
class OutgoingMessageHolder extends RecyclerView.ViewHolder {
#BindView(R.id.messageText) TextView mMessageText;
#BindView(R.id.messageTime) TextView mMessageTime;
OutgoingMessageHolder(View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
}
#Override
public int getItemViewType(int position) {
Log.d("ChatActivity Adapter","getItemViewType "+mChatMessages.get(position).getMessageStatus());
if (mChatMessages.get(position).getMessageStatus() == 2){
return 1;
} else {
return 0;
}
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Log.d("ChatActivity Adapter","onCreateViewHolder");
switch (viewType){
case 0 :
View outgoingMessageView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_outcoming_text_message,parent,false);
return new OutgoingMessageHolder(outgoingMessageView);
default :
View incomingMessageView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_incoming_text_message, parent, false);
return new IncomingMessageHolder(incomingMessageView);
}
}
#Override
public void onBindViewHolder(#NonNull final RecyclerView.ViewHolder holder, int position) {
Log.d("ChatActivity Adapter","onBindViewHolder");
switch (holder.getItemViewType()){
case 0:
OutgoingMessageHolder outgoingMessageHolder = (OutgoingMessageHolder) holder;
outgoingMessageHolder.mMessageText.setText(mChatMessages.get(position).getMessage());
outgoingMessageHolder.mMessageTime.setText(
UtilsFuntions.getDurationString(mChatMessages.get(position).getTimeStamp())
);
break;
case 1:
IncomingMessageHolder incomingMessageHolder = (IncomingMessageHolder) holder;
incomingMessageHolder.mMessageText.setText(mChatMessages.get(position).getMessage());
incomingMessageHolder.mMessageTime.setText(
UtilsFuntions.getDurationString(mChatMessages.get(position).getTimeStamp())
);
break;
}
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemCount() {
Log.d("ChatActivity Adapter", String.valueOf(mChatMessages.size()));
return mChatMessages.size();
}
}
Code for initalizing recyclerView:
mLayoutManager = new LinearLayoutManager(getApplicationContext());
mLayoutManager.setItemPrefetchEnabled(true);
mChatMessages.setItemViewCacheSize(0);
mChatMessages.setDrawingCacheEnabled(true);
mChatMessages.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
mChatMessages.setLayoutManager(mLayoutManager);
mChatMessages.setHasFixedSize(true);
mChatMessagesAdapter = new ChatMessagesAdapter(mChatItems,
getApplicationContext());
mChatMessages.addOnScrollListener(listerOnScroll);
mChatMessages.setAdapter(mChatMessagesAdapter);
ChatMessages chatMessage = new ChatMessages();
chatMessage.setMessage(mChatMessage.getText().toString().trim());
chatMessage.setMessageStatus(2);
chatMessage.setTimeStamp(System.currentTimeMillis());
mChatItems.add(chatMessage);
mChatMessagesAdapter.refreshData(mChatItems);
But when even I touch recyclerview or try to scroll recyclerview all callbacks called and recyclerview get populated. I don't know why this is happening. Please help me to solve this
I try to use a GridView object in a specific fragment in my app.
I created a layout file for the grid item and in the layout editor, the preview image looks good, as expected.
The problem arises when I run the app in my emulator. The whole item layout gets shrinked and the image I put in the middle suddenly jumps to the top of the layout.
Screenshot of the layout editor:
https://i.gyazo.com/8ed96ed19719a578388cc48aba6829f8.png
Screenshot of the emulator:
https://i.gyazo.com/cca0a32b3d102025df5d5369dc7c0efc.png
Here is the xml code for the fragment:
<?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">
<GridView
android:id="#+id/documents_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:columnWidth="#dimen/document_grid_item_width"
android:gravity="center"
android:horizontalSpacing="0dp"
android:verticalSpacing="0dp"
android:numColumns="auto_fit"
android:stretchMode="spacingWidthUniform" />
<RelativeLayout
android:id="#+id/empty_view_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/empty_view_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:src="#drawable/recent_empty_view" />
<ImageView
android:id="#+id/empty_view_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="#+id/empty_view_image"
android:layout_below="#+id/empty_view_image"
android:layout_marginEnd="7dp"
android:scaleX="0.75"
android:scaleY="0.75"
android:src="#drawable/empty_view_arrow" />
</RelativeLayout>
</RelativeLayout>
Here is the item layout xml code:
<?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:layout_width="#dimen/document_grid_item_width"
android:layout_height="#dimen/document_grid_item_height"
android:gravity="center"
android:orientation="vertical"
android:weightSum="1">
<FrameLayout
android:id="#+id/draft_frame"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.9"
android:background="#drawable/document_grid_item_bg"
android:focusable="true"
android:foreground="?android:selectableItemBackground">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/draft_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="#drawable/draft_icon" />
<ImageView
android:id="#+id/draft_more_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginTop="5dp"
app:srcCompat="#drawable/ic_more" />
</RelativeLayout>
</FrameLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="5dp"
android:layout_weight="0.1">
<TextView
android:id="#+id/draft_date_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="20 May 17"
android:textSize="11sp" />
</RelativeLayout>
</LinearLayout>
Here is the adapter code:
package com.silverfix.dgdeditor.adapters;
import android.app.Activity;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.silverfix.dgdeditor.R;
import com.silverfix.dgdeditor.utils.DocumentPack;
import com.silverfix.dgdeditor.utils.views.ViewClickListener;
import com.silverfix.dgdeditor.utils.views.ViewLongClickListener;
import java.util.List;
/**
* Created by David on 14/05/2017.
*/
public class DraftsGridAdapter extends BaseAdapter {
// Listeners
private ViewClickListener clickListener;
private ViewLongClickListener longClickListener;
private Activity context;
private List<DocumentPack> dataSet;
private int clickedItemPos = -1;
public DraftsGridAdapter(Activity context, List<DocumentPack> dataSet) {
this.context = context;
this.dataSet = dataSet;
}
public void setClickedItemPosition(int clickedItemPos) {
this.clickedItemPos = clickedItemPos;
}
public int getClickedItemPosition() {
return clickedItemPos;
}
public void setClickListener(ViewClickListener clickListener) {
this.clickListener = clickListener;
}
public void setLongClickListener(ViewLongClickListener longClickListener) {
this.longClickListener = longClickListener;
}
#Override
public int getCount() {
return dataSet.size();
}
#Override
public Object getItem(int position) {
return dataSet.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final DocumentPack pack = dataSet.get(position);
if (convertView == null) {
final LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.draft_grid_item, null);
DraftViewHolder viewHolder = new DraftViewHolder(context, convertView);
convertView.setTag(viewHolder);
}
// Instance of a view holder from the tag of the convertView
DraftViewHolder viewHolder = (DraftViewHolder) convertView.getTag();
// Set the adapter position to the current view holder
viewHolder.setAdapterPosition(position);
// Bind the click listeners to the root view of the view holder
// viewHolder.bindClick(clickListener);
// viewHolder.bindLongClick(longClickListener);
// Bind the data to the view holder
viewHolder.bindData(pack);
return convertView;
}
private class DraftViewHolder implements View.OnCreateContextMenuListener {
private View.OnClickListener clickListener;
private View.OnLongClickListener onLongClickListener;
private View rootView;
private ImageView moreButton;
private TextView date;
private int position;
public DraftViewHolder(final Activity context, final View rootView) {
this.rootView = rootView;
date = (TextView) rootView.findViewById(R.id.draft_date_tv);
moreButton = (ImageView) rootView.findViewById(R.id.draft_more_button);
context.registerForContextMenu(rootView);
rootView.setOnCreateContextMenuListener(this);
moreButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
context.openContextMenu(rootView);
setClickedItemPosition(position);
}
});
}
void setAdapterPosition(int position) {
this.position = position;
}
void bindClick(final ViewClickListener clickListener) {
this.clickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
clickListener.onClick(position);
}
};
rootView.setOnClickListener(this.clickListener);
}
void bindLongClick(final ViewLongClickListener longClickListener) {
this.onLongClickListener = new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
longClickListener.onLongClick(position);
return false;
}
};
rootView.setOnLongClickListener(this.onLongClickListener);
}
void bindData(DocumentPack draft) {
String formatDate = draft.getFormattedDate();
date.setText(formatDate);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
}
}
}
This worked for me, You can try...
`<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="5dp" >
<GridView
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="100dp"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="3"
android:stretchMode="spacingWidthUniform"
android:verticalSpacing="10dp" />
`
If this don't work you can also try to use android:stretchMode="columnWidth"
I am using Recyclerview and my onCreateViewHolder and onBindViewHolder are not called. I am getting the data but it is not displaying.
My adapter class
public class DishesAdapter extends RecyclerView.Adapter<DishesAdapter.MyViewHolder> {
private Context mContext;
List<List> DialogList = new ArrayList<List>();
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView dishnames;
public RatingBar dishratings;
public ImageView dishimages;
private ImageLoader mLoader;
public MyViewHolder(View view) {
super(view);
Log.d("follower2","hi");
dishnames = (TextView)view.findViewById(R.id.dishname);
dishimages = (ImageView)view.findViewById(R.id.dishimage);
dishratings=(RatingBar)view.findViewById(R.id.dishrating);
}
}
public DishesAdapter(Context mContext, List objects) {
super();
Log.d("follower1","hi");
this.mContext = mContext;
this.DialogList = objects;
Log.d("follower1",objects.toString());
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mContext)
.inflate(R.layout.recipe_list, parent, false);
Log.d("follower","hi");
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
final int i=position;
Log.d("follower","hi");
List dialog = DialogList.get(i);
Log.d("follower",dialog.toString());
String dishid = dialog.get(0).toString();
final String dishname = dialog.get(1).toString();
//byte[] dishimage = Base64.decode(dialog.get(2).toString(), Base64.DEFAULT);
String dishimage=dialog.get(2).toString();
String rating=dialog.get(3).toString();
holder.dishnames.setText(dishname);
holder.dishratings.setRating(Float.parseFloat(rating));
holder.mLoader.DisplayImage(dishimage.replaceAll(" ", "%20"),holder.dishimages);
}
#Override
public int getItemCount() {
return DialogList.size();
}}
Recyclerview
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(mLayoutManager);
xml
<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"
xmlns:tools="http://schemas.android.com/tools"
tools:context="mealplanner.com.main.mealplanner.MainActivity"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:scrollbars="vertical" />
</LinearLayout>
Row List
<?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.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
card_view:cardUseCompatPadding="true"
card_view:cardElevation="4dp"
card_view:cardCornerRadius="3dp"
android:id="#+id/cv">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<ImageView
android:id="#+id/dishimage"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginRight="6dip"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:layout_margin="10dp"
android:src="#drawable/portraitlanding"
/>
<TextView
android:id="#+id/dishname"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_toRightOf="#+id/dishimage"
android:textColor="#000000"
android:textSize="20dp"
android:layout_gravity="center"
android:text="Andrew" />
<RatingBar
android:id="#+id/dishrating"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/ratingBarStyleSmall"
android:isIndicator="true"
android:numStars="5"
android:stepSize="0.1"
android:layout_marginTop="10dp"
android:layout_gravity="center"
android:layout_below="#+id/dishname"
android:layout_toRightOf="#+id/dishimage"
/>
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
DishesAdapter constructor is being called. I am getting follower1 log along with the list of items.
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingTop="#dimen/activity_horizontal_margin"
android:background="#android:color/transparent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/string_for_newsletter"
android:paddingLeft="16dp"
android:id="#+id/textQuestion"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/bookmark_star"
android:layout_alignParentRight="true"
android:background="#android:color/transparent"
android:layout_alignParentBottom="true"
android:id="#+id/bookmarkButton"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/textQuestion"
android:text="answer"
android:paddingLeft="16dp"
android:paddingTop="16dp"
android:textColor="#00ff00"
android:visibility="gone"
android:id="#+id/textAnswer"/>
</RelativeLayout>
this is my layout for card view
and below is the code for RecyclerView Adapter
package com.example.user_2.tcc_app.QuestionAnswer;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
import com.example.user_2.tcc_app.R;
/**
* Created by USER-2 on 23-Feb-15.
*/
public class QuestionAnswerAdapter extends RecyclerView.Adapter<QuestionAnswerAdapter.QuestionAnswerAdapterViewHolder>{
int length;
int layout_id;
public long item_id;
public QuestionAnswerAdapter(int length, int id_for_layout){
this.length = length;
this.layout_id = id_for_layout;
}
#Override
public QuestionAnswerAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View root = LayoutInflater.from(parent.getContext()).inflate(layout_id, parent, false);
QuestionAnswerAdapterViewHolder questionAnswerAdapterViewHolder = new QuestionAnswerAdapterViewHolder(root);
return questionAnswerAdapterViewHolder;
}
#Override
public void onBindViewHolder(final QuestionAnswerAdapterViewHolder holder, int position) {
}
#Override
public int getItemCount() {
return length;
}
public class QuestionAnswerAdapterViewHolder extends RecyclerView.ViewHolder{
TextView textQuestion;
ImageButton bookmarkButton;
TextView textAnswer;
public QuestionAnswerAdapterViewHolder(View v){
super(v);
textQuestion = (TextView)v.findViewById(R.id.textQuestion);
bookmarkButton = (ImageButton)v.findViewById(R.id.bookmarkButton);
textAnswer = (TextView)v.findViewById(R.id.textAnswer);
textQuestion.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
textAnswer.setVisibility(View.GONE);
}
});
}
}
}
I have 10 Items in the recyclerview. I want to show the textview with id textAnswer when textQuestion is clicked and every thing is working fine till now but when i scroll down i can see that ninth item also has the textAnswer field visible. I can understand that this is happening due to onBindViewHolder Method as recyclerView while recycling its item uses previously visible items which are not visible any more. But i have no clue on how to sort it out. Some one please help
The RecyclerView re-uses the ViewHolders so the trick is to set the expandable area to VISIBLE/GONE inside the onBindViewHolder() method. Hopefully you solved your problem by now but for those who run into similar issues like me, a functional example:
An example of an adapter with expendable cardViews:
public class FooAdapter extends RecyclerView.Adapter<FooAdapter.ViewHolder> {
List<LightGroup> mFoos;
List<Boolean> mExpandedFoos;
public GroupAdapter(List<Foo> Foos) {
mFoos = foos;
mExpandedFoos = new ArrayList<>(mFoos.size());
for(int i = 0; i < mGroups.size(); i++){
mExpandedFoos.add(false);
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.foo_row, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
if(mExpandedFoos.get(position)) {
holder.expandableLayout.setVisibility(View.VISIBLE);
} else {
holder.expandableLayout.setVisibility(View.GONE);
}
Foo foo = mFoos.get(position);
holder.fooName.setText(foo.getName());
//Setup the rest of your row views from your Foo object
}
#Override
public int getItemCount() {
return mFoos == null ? 0 : mFoos.size();
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView fooName;
ViewGroup expandableLayout;
ImageButton expandButton;
public ViewHolder(View itemView) {
super(itemView);
fooName = (TextView) itemView.findViewById(R.id.foo_name_textview);
expandableLayout = (ViewGroup) itemView.findViewById(R.id.expandable_part_layout);
expandButton = (ImageButton) itemView.findViewById(R.id.foo_row_expand_button);
expandButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int position = getAdapterPosition();
if(v.getId() == expandButton.getId()){
if(mExpandedFoos.get(position)) {
expandableLayout.setVisibility(View.GONE);
} else {
expandableLayout.setVisibility(View.VISIBLE);
}
mExpandedFoos.set(position, !mExpandedFoos.get(position));
}
}
}
}
With layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.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:cardCornerRadius="4dp"
app:cardPreventCornerOverlap="false"
android:background="#android:color/background_dark"
android:layout_marginBottom="8dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/top_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="false"
android:layout_alignParentTop="true">
<TextView
android:id="#+id/foo_name_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="#dimen/activity_horizontal_margin"
android:paddingEnd="#dimen/activity_horizontal_margin"
android:gravity="center"/>
<ImageButton
android:id="#+id/foo_row_expand_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="?android:selectableItemBackground"
android:clickable="true"
android:padding="6dp"
android:rotation="90"
android:src="#drawable/ic_play_light" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/expandable_part_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/top_layout"
android:animateLayoutChanges="true"
android:clickable="false"
android:visibility="gone">
<!-- Your expanded content views go here -->
</RelativeLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>