Chat Bubble Alignment on ListView - android

I have connected my android application to Firebase and I am sending messages with attributes 'name' and 'status'. status being either sent or received.
I am facing issue while aligning the chat bubble left/right depending upon the status.
Here is the code snippet
message_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/singleMessageContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/message_bubble_received">
<TextView
android:id="#+id/username_text_view"
android:layout_width="wrap_content"
android:paddingLeft="10dip"
android:layout_margin="5dip"
android:text="Hello bubbles!"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/message_text_view"
android:layout_width="wrap_content"
android:paddingLeft="1dip"
android:layout_margin="5dip"
android:text="Hello bubbles!"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ECECEC">
<ListView
android:id="#+id/listView"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:divider="#null"
android:layout_marginTop="10dp"
android:listSelector="#android:color/transparent"
android:transcriptMode="alwaysScroll"
android:layout_marginBottom="80dp"/>
<RelativeLayout
android:id="#+id/form"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<EditText
android:id="#+id/message_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="left"
android:layout_marginLeft="5dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="5dp"
android:layout_weight="3"
android:autoText="true"
android:background="#drawable/note_backgroud"
android:hint="Write your question here"
android:minLines="1"
android:paddingLeft="20dp"
android:paddingRight="8dp"
android:paddingBottom="16dp"
android:paddingTop="8dp"/>
<ImageButton
android:id="#+id/cameraButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#null"
android:src="#drawable/camera"
android:gravity="top|right"
android:layout_marginRight="8dp"
android:layout_marginLeft="-52dp"
/>
<ImageButton
android:id="#+id/chatSendButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/sent"
android:background="#null"
android:layout_gravity="center"
android:layout_marginRight="8dp"
android:layout_marginLeft="8dp"
android:text="Send"
android:onClick="onSendButtonClick"
android:textColor="#ffffff" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
Following is the code snipet for the MessageAdapter
MessageAdapter.java
public abstract class MessageAdapter<T> extends BaseAdapter {
private Query mRef;
private Class<T> mModelClass;
private int mLayout;
private LayoutInflater mInflater;
private List<T> mModels;
private List<String> mKeys;
private ChildEventListener mListener;
private Context context;
private LinearLayout message_row;
private ProgressDialog mProgressDialog;
public MessageAdapter(Query mRef, Class<T> mModelClass, int mLayout, Activity activity) {
this.mRef = mRef;
this.mModelClass = mModelClass;
this.mLayout = mLayout;
this.context = activity.getApplicationContext();
mInflater = activity.getLayoutInflater();
mModels = new ArrayList<T>();
mKeys = new ArrayList<String>();
mProgressDialog = new ProgressDialog(activity);
mProgressDialog.show();
// Look for all child events. We will then map them to our own internal ArrayList, which backs ListView
mListener = this.mRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
T model = dataSnapshot.getValue(MessageAdapter.this.mModelClass);
String key = dataSnapshot.getKey();
// Insert into the correct location, based on previousChildName
if (previousChildName == null) {
mModels.add(0, model);
mKeys.add(0, key);
} else {
int previousIndex = mKeys.indexOf(previousChildName);
int nextIndex = previousIndex + 1;
if (nextIndex == mModels.size()) {
mModels.add(model);
mKeys.add(key);
} else {
mModels.add(nextIndex, model);
mKeys.add(nextIndex, key);
}
}
notifyDataSetChanged();
mProgressDialog.dismiss();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
// One of the mModels changed. Replace it in our list and name mapping
String key = dataSnapshot.getKey();
T newModel = dataSnapshot.getValue(MessageAdapter.this.mModelClass);
int index = mKeys.indexOf(key);
mModels.set(index, newModel);
notifyDataSetChanged();
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
// A model was removed from the list. Remove it from our list and the name mapping
String key = dataSnapshot.getKey();
int index = mKeys.indexOf(key);
mKeys.remove(index);
mModels.remove(index);
notifyDataSetChanged();
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
// A model changed position in the list. Update our list accordingly
String key = dataSnapshot.getKey();
T newModel = dataSnapshot.getValue(MessageAdapter.this.mModelClass);
int index = mKeys.indexOf(key);
mModels.remove(index);
mKeys.remove(index);
if (previousChildName == null) {
mModels.add(0, newModel);
mKeys.add(0, key);
} else {
int previousIndex = mKeys.indexOf(previousChildName);
int nextIndex = previousIndex + 1;
if (nextIndex == mModels.size()) {
mModels.add(newModel);
mKeys.add(key);
} else {
mModels.add(nextIndex, newModel);
mKeys.add(nextIndex, key);
}
}
notifyDataSetChanged();
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Log.e("FirebaseListAdapter", "Listen was cancelled, no more updates will occur");
}
});
}
public void cleanup() {
// We're being destroyed, let go of our mListener and forget about all of the mModels
mRef.removeEventListener(mListener);
mModels.clear();
mKeys.clear();
}
#Override
public int getCount() {
return mModels.size();
}
#Override
public Object getItem(int i) {
return mModels.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (view == null) {
view = mInflater.inflate(mLayout, viewGroup, false);
message_row = (LinearLayout) view.findViewById(R.id.singleMessageContainer);
}
T model = mModels.get(i);
Message m = (Message) model;
Log.i("status", m.getStatus());
if (m.getStatus().equals("sent")){
message_row.setGravity(Gravity.LEFT);
message_row.setBackgroundResource(R.drawable.message_bubble_received);
}
else {
message_row.setGravity(Gravity.RIGHT);
message_row.setBackgroundResource(R.drawable.message_bubble_sent);
}
// Call out to subclass to marshall this model into the provided view
populateView(view, model);
return view;
}
protected abstract void populateView(View v, T model);
}
I noticed that the getView() is called more times than the count in the list (eg : if I have 2 messages getview() is called 4 to 5 times).
With the current code chat bubbles are always to the left irrespective of the chat status.
Firebase Data

I recommend to use two layouts - for your bubbles and your opponent. Use them in getView() method of your adapter. For list_item_message_own.xml use right allignment and for list_item_message_opponent.xml use left allignment, it depends on message status.
#Override
public View getView(Context context, Cursor cursor, ViewGroup parent) {
View view;
ViewHolder viewHolder = new ViewHolder();
MessageCache messageCache = ChatManager.getMessageCacheFromCursor(cursor);
boolean ownMessage = isOwnMessage(messageCache.getSenderId());
if (messageCache.getMessagesNotificationType() == null) {
if (ownMessage) {
view = layoutInflater.inflate(R.layout.list_item_message_own, null, true);
} else {
view = layoutInflater.inflate(R.layout.list_item_message_opponent, null, true);
}
viewHolder.timeAttachMessageTextView = (TextView) view.findViewById(R.id.time_attach_message_textview);
viewHolder.verticalProgressBar.setProgressDrawable(context.getResources().getDrawable(R.drawable.vertical_progressbar));
viewHolder.centeredProgressBar = (ProgressBar) view.findViewById(R.id.centered_progressbar);
} else {
view = layoutInflater.inflate(R.layout.list_item_notification_message, null, true);
viewHolder.messageTextView = (EmojiTextView) view.findViewById(R.id.message_textview);
viewHolder.timeTextMessageTextView = (TextView) view.findViewById(
R.id.time_text_message_textview);
}
view.setTag(viewHolder);
return view;
}

Related

Unable to display fetch data from MYSQL database in custom gridview in android

In my app I use grid view to display data. grid view is in a fragment.I already retrieve data from mysql database in Log cat but that json data not display in custom grid.
activity_product_list.xml
<android.support.constraint.ConstraintLayout 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="match_parent"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".DrawerActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/header2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PRODUCTS : -"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#color/blue"/>
<GridView
android:id="#+id/productlist"
android:layout_below="#+id/header2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:numColumns="2"
android:horizontalSpacing="2dp"
android:layout_marginTop="#dimen/activity_horizontal_margin">
</GridView>
</RelativeLayout>
ProductListFragment.java
public class ProductListFragment extends Fragment {
List<Product> productList;
GridView gridView;
CustomProductList customProductList;
int categoryid;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_product_list, container,false);
gridView = (GridView) rootView.findViewById(R.id.productlist);
final GlobalVariable ID = (GlobalVariable)getActivity().getApplication();
categoryid = ID.getCategoryid();
productList = new ArrayList<>();
loadProduct();
customProductList = new CustomProductList(getActivity(),productList);
gridView.setAdapter(customProductList);
return rootView;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
private void loadProduct() {
String PRODUCT_URL = "http://192.168.0.101/cart/product/get_all_product.php?vcategoryid="+categoryid;
StringRequest stringRequest= new StringRequest(Request.Method.GET, PRODUCT_URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject obj = new JSONObject(response);
JSONArray array = obj.getJSONArray("products");
for (int i = 0; i < array.length(); i++){
//getting the user from the response
JSONObject userJson = array.getJSONObject(i);
Product product = new Product();
product.setProductid(userJson.getInt("productid"));
product.setProductName(userJson.getString("productname"));
product.setProductDesc(userJson.getString("productdesc"));
product.setPrice(userJson.getString("productprice"));
productList.add(product);
Log.e("product",userJson+"");
}
customProductList.notifyDataSetChanged();
Log.e("product",customProductList+"");
//customCategoryList = new CustomCategoryList(getActivity(),categoryList);
//recyclerView.setAdapter(customCategoryList);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Volley.newRequestQueue(getActivity()).add(stringRequest);
}
}
custom_product_list.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:src="#drawable/home_appliances"/>
<TextView
android:id="#+id/productName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Redmi"
android:textStyle="bold"
android:textColor="#color/black"
android:textSize="22sp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RS."
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#color/black"/>
<TextView
android:id="#+id/price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="9999"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#color/blue"
android:layout_marginLeft="10dp"/>
</LinearLayout>
CustomProductList.java
public class CustomProductList extends BaseAdapter {
private Context mCtx;
private List<Product> productList;
public CustomProductList(Context mCtx, List<Product> productList) {
this.mCtx = mCtx;
this.productList = productList;
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mCtx
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(mCtx);
// get layout from mobile.xml
gridView = inflater.inflate(R.layout.custom_product_list, null);
TextView productname = (TextView) gridView.findViewById(R.id.productName);
TextView price = (TextView) gridView.findViewById(R.id.price);
// getting data for the row
Product product = productList.get(position);
// set data
productname.setText(product.getProductName());
price.setText(product.getPrice());
} else {
gridView = (View) convertView;
}
return gridView;
}
}
This is my code.All data comes from database in logcat as json..But All not display in grid.Please help me.Tell me What is the problem.
Solution:
You forgot to get count the updated list, hence chenge the below code:
#Override
public int getCount() {
return 0;
}
to this:
#Override
public int getCount() {
return this.productList.size();
}
That's it. Hope it helps.

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

How to update imageview from the parent recyclerview after click on nested recyclerview's imageview

Please check following screenshot, I want to update imageview from parent recyclerview when user click on imageview from nested recyclerview.
I have taken two individual adapters for for parent & nested recyclerview.I am not able to do the functionality for updating image, kindly help.
Parent Recyclerview Adapter:
public class RecyclerViewDataAdapter extends RecyclerView.Adapter<RecyclerViewDataAdapter.ItemRowHolder> {
private ArrayList<PLDModel> dataList;
private Context mContext;
public RecyclerViewDataAdapter(Context context, ArrayList<PLDModel> dataList) {
this.dataList = dataList;
this.mContext = context;
}
#Override
public ItemRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_card_view, null);
ItemRowHolder mh = new ItemRowHolder(v);
return mh;
}
#Override
public void onBindViewHolder(ItemRowHolder itemRowHolder, int i) {
final String itemTitle = dataList.get(i).getTitle();
final String itemDescription = dataList.get(i).getDescription();
ArrayList<SmallImages> singleSectionItems = dataList.get(i).getSmallImages();
itemRowHolder.itemTitle.setText(Html.fromHtml("<b>" + itemTitle + " </b> " + itemDescription));
SectionListDataAdapter itemListDataAdapter = new SectionListDataAdapter(mContext, singleSectionItems);
itemRowHolder.recyclerSmallImageList.setHasFixedSize(true);
itemRowHolder.recyclerSmallImageList.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
itemRowHolder.recyclerSmallImageList.setAdapter(itemListDataAdapter);
}
#Override
public int getItemCount() {
return (null != dataList ? dataList.size() : 0);
}
public class ItemRowHolder extends RecyclerView.ViewHolder {
protected TextView itemTitle, expandImage;
protected ImageView bookmarkImage,largeImage;
protected RecyclerView recyclerSmallImageList;
protected Button btnMore;
public ItemRowHolder(View view) {
super(view);
this.itemTitle = (TextView) view.findViewById(R.id.title);
this.bookmarkImage = (ImageView) view.findViewById(R.id.bookmark);
this.largeImage = (ImageView) view.findViewById(R.id.large_image);
this.expandImage = (TextView) view.findViewById(R.id.expand);
this.recyclerSmallImageList = (RecyclerView) view.findViewById(R.id.recycler_small_image_list);
}
}
}
Nested Recyclerview Adapter:
public class SectionListDataAdapter extends RecyclerView.Adapter<SectionListDataAdapter.SingleItemRowHolder> {
private ArrayList<SmallImages> itemsList;
private Context mContext;
public SectionListDataAdapter(Context context, ArrayList<SmallImages> itemsList) {
this.itemsList = itemsList;
this.mContext = context;
}
#Override
public SingleItemRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.small_images_view, null);
SingleItemRowHolder mh = new SingleItemRowHolder(v);
return mh;
}
#Override
public void onBindViewHolder(SingleItemRowHolder holder, int i) {
SmallImages singleItem = itemsList.get(i);
}
#Override
public int getItemCount() {
return (null != itemsList ? itemsList.size() : 0);
}
public class SingleItemRowHolder extends RecyclerView.ViewHolder {
protected ImageView itemImage;
public SingleItemRowHolder(View view) {
super(view);
//this.tvTitle = (TextView) view.findViewById(R.id.tvTitle);
this.itemImage = (ImageView) view.findViewById(R.id.item_small_image);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Toast.makeText(v.getContext(), tvTitle.getText(), Toast.LENGTH_SHORT).show();
}
});
}
}
}
Using two Recyclerview will be hard to control rather than use a Single adapter and control everything from there.I have just worked on this type of thing that's why I am posting my code there may be some unwanted code which u may need.
/////Adapter class
public class AdapterTodayTrip extends RecyclerView.Adapter<AdapterTodayTrip.VHItem> {
private Context mContext;
private int rowLayout;
private List<ModelRouteDetailsUp> dataMembers;
private ArrayList<ModelRouteDetailsUp> arraylist;
private ArrayList<ModelKidDetailsUp> arraylist_kids;
List<String> wordList = new ArrayList<>();
Random rnd = new Random();
int randomNumberFromArray;
private ModelRouteDetailsUp personaldata;
private ProgressDialog pDialog;
private ConnectionDetector cd;
String img_baseurl = "";
String item = "";
public AdapterTodayTrip(Context mcontext, int rowLayout, List<ModelRouteDetailsUp> tripList, String flag, String img_baseurl) {
this.mContext = mcontext;
this.rowLayout = rowLayout;
this.dataMembers = tripList;
wordList.clear();
this.img_baseurl = img_baseurl;
arraylist = new ArrayList<>();
arraylist_kids = new ArrayList<>();
arraylist.addAll(dataMembers);
cd = new ConnectionDetector(mcontext);
pDialog = KPUtils.initializeProgressDialog(mcontext);
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public AdapterTodayTrip.VHItem onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(rowLayout, viewGroup, false);
return new AdapterTodayTrip.VHItem(v);
}
#Override
public int getItemCount() {
return dataMembers.size();
}
#Override
public void onBindViewHolder(final AdapterTodayTrip.VHItem viewHolder, final int position) {
viewHolder.setIsRecyclable(false);
try {
personaldata = dataMembers.get(position);
if (!KPHashmapUtils.m_ride_route_details_up.get(position).getKidpool_route_id().isEmpty() && !KPHashmapUtils.m_ride_route_details_up.get(position).getKidpool_route_id().equals("null")) {
viewHolder.tv_trip_id.setText("#" + KPHashmapUtils.m_ride_route_details_up.get(position).getKidpool_route_id());
}
****///////inflate the child list here and onclick on the image below in the inflated view it will load the image in the main view****
if (personaldata.getKidlist().size() > 0) {
viewHolder.linear_childview.setVisibility(View.VISIBLE);
viewHolder.tv_total_count.setText(""+personaldata.getKidlist().size());
viewHolder.id_gallery.removeAllViews();
LinearLayout.LayoutParams buttonLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
buttonLayoutParams.setMargins(0, 0, 8, 0);
LayoutInflater layoutInflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < personaldata.getKidlist().size(); i++) {
View view = layoutInflater.inflate(R.layout.view_child_list, null);
view.setLayoutParams(buttonLayoutParams);
RelativeLayout rl_txt = (RelativeLayout)view.findViewById(R.id.rl_txt);
RelativeLayout rl_img = (RelativeLayout)view.findViewById(R.id.rl_img);
TextView tv_count = (TextView)view.findViewById(R.id.tv_count);
com.app.kidpooldriver.helper.CircularTextView tv_name = (com.app.kidpooldriver.helper.CircularTextView)view.findViewById(R.id.tv_name);
final CircleImageView iv_circular = (CircleImageView)view.findViewById(R.id.iv_circular);
int count = i + 1;
String count1 = "0";
if (count <= 10) {
count1 = "0" + count;
}
tv_count.setText(String.valueOf(count1));
viewHolder.id_gallery.addView(view);
final String baseurl = img_baseurl + "" + personaldata.getKidlist().get(i).getKid_image();
**/////set the url of the small image in the tag here**
if(!baseurl.isEmpty()) {
iv_circular.setTag(baseurl);
}
if (!personaldata.getKidlist().get(i).getKid_image().isEmpty()) {
GradientDrawable bgShape = (GradientDrawable) rl_img.getBackground();
bgShape.setColor(Color.parseColor("#A6b1a7a6"));
rl_txt.setVisibility(View.GONE);
//rl_img.setVisibility(View.VISIBLE);
tv_name.setVisibility(View.GONE);
Log.d("aimg_baseurl", baseurl);
try {
Picasso.with(mContext)
.load(baseurl)
.resize(60,60)
.centerCrop()
.into(iv_circular);
iv_circular.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String url=iv_circular.getTag().toString().trim();
if(!url.isEmpty())
KPUtils.showToastShort(mContext,url);
Picasso.with(mContext)
.load(url)
.resize(60,60)
.centerCrop()
.into(viewHolder.img_child);
}
});
} catch (Exception e) {
}
} else {
}
}
}else{
viewHolder.linear_childview.setVisibility(View.GONE);
}
} catch (Exception e) {
e.printStackTrace();
}
}
class VHItem extends RecyclerView.ViewHolder {
CardView cv_members;
ImageView img_child;
TextView tv_trip_id, tv_trip_status, tv_vehicle_number, tv_trip_start_time, tv_trip_end_time, tv_trip_way, tv_total_count;
LinearLayout id_gallery,linear_childview;
public VHItem(View itemView) {
super(itemView);
img_child= (ImageView) itemView.findViewById(R.id.img_child);
cv_members = (CardView) itemView.findViewById(R.id.cv_members);
tv_trip_id = (TextView) itemView.findViewById(R.id.tv_trip_id);
tv_trip_status = (TextView) itemView.findViewById(R.id.tv_trip_status);
tv_vehicle_number = (TextView) itemView.findViewById(R.id.tv_vehicle_number);
tv_trip_start_time = (TextView) itemView.findViewById(R.id.tv_trip_start_time);
tv_trip_end_time = (TextView) itemView.findViewById(R.id.tv_trip_end_time);
tv_trip_way = (TextView) itemView.findViewById(R.id.tv_trip_way);
tv_total_count = (TextView) itemView.findViewById(R.id.tv_total_count);
id_gallery = (LinearLayout) itemView.findViewById(R.id.id_gallery);
linear_childview= (LinearLayout) itemView.findViewById(R.id.linear_childview);
}
}
}
/////////////////////////// this layout is inflated in every row
view_child_list
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/iv_circular"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="#mipmap/ic_launcher"
app:civ_border_color="#d27959"
app:civ_border_width="1dp" />
<RelativeLayout
android:id="#+id/rl_txt"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:background="#drawable/gy_ring_circular"
android:gravity="center"
android:visibility="gone">
<com.app.kidpooldriver.helper.CircularTextView
android:id="#+id/tv_name"
fontPath="fonts/Poppins-Bold.ttf"
android:layout_width="70dp"
android:layout_height="70dp"
android:gravity="center"
android:text="01"
android:textColor="#color/white"
android:textSize="35sp"
tools:ignore="MissingPrefix" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/rl_img"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:background="#drawable/gy_ring_circular"
android:gravity="center"
android:visibility="visible">
<TextView
android:id="#+id/tv_count"
fontPath="fonts/Poppins-Bold.ttf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="01"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Medium"
android:textColor="#ffffff"
android:textStyle="bold"
tools:ignore="MissingPrefix" />
</RelativeLayout>
</FrameLayout>
///// this is the mianlayout which is inflated.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/cv_members"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/card_margin"
android:elevation="#dimen/elevation"
card_view:cardCornerRadius="5dp">
<LinearLayout
android:id="#+id/main_body"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:layout_marginTop="#dimen/fifteen"
android:orientation="horizontal"
android:paddingLeft="#dimen/ten">
<TextView
android:id="#+id/tv_trip_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#KD09201701"
android:textColor="#color/colorPrimary"
android:textSize="#dimen/twenty"
android:textStyle="bold" />
<TextView
android:id="#+id/tv_trip_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/light_green"
android:gravity="center"
android:padding="5dp"
android:text="In Progress"
android:textAppearance="#style/TextAppearance.AppCompat.Small"
android:textColor="#color/black" />
</LinearLayout>
<TextView
android:id="#+id/tv_vehicle_number"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="20dp"
android:text="Route 26U-26D"
android:visibility="gone"
android:textAppearance="#style/TextAppearance.AppCompat.Small"
android:textColor="#color/route_textcolor" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="horizontal">
<TextView
android:id="#+id/tv_trip_start_time"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="match_parent"
android:layout_marginTop="#dimen/five"
android:paddingLeft="20dp"
android:text="06:30am"
android:textAppearance="#style/TextAppearance.AppCompat.Medium"
android:textColor="#color/grey_textcolor" />
<TextView
android:id="#+id/tv_trip_end_time"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="#dimen/five"
android:paddingLeft="20dp"
android:text="08:30am"
android:textAppearance="#style/TextAppearance.AppCompat.Medium"
android:textColor="#color/grey_textcolor"
android:visibility="gone" />
</LinearLayout>
<TextView
android:id="#+id/tv_trip_way"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="#dimen/five"
android:paddingLeft="20dp"
android:visibility="gone"
android:paddingRight="20dp"
android:text="Chingrighata > NiccoPark > SDF > College More > DLF 1 > Eco Space"
android:textAppearance="#style/TextAppearance.AppCompat.Small"
android:textColor="#color/grey_textcolor"
android:textStyle="normal" />
<ImageView
android:id="#+id/img_child"
android:layout_width="200dp"
android:layout_gravity="center"
android:layout_height="200dp" />
<LinearLayout
android:id="#+id/linear_childview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="#dimen/fifteen"
android:orientation="horizontal">
<HorizontalScrollView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:scrollbars="none">
<LinearLayout
android:id="#+id/id_gallery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="horizontal" />
</HorizontalScrollView>
<LinearLayout
android:layout_width="70dp"
android:layout_height="70dp"
android:background="#drawable/ly_ring_circular"
android:gravity="center_vertical">
<TextView
android:id="#+id/tv_total_count"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:ignore="MissingPrefix"
fontPath="fonts/Poppins-Bold.ttf"
android:text="+20"
android:textAppearance="#style/TextAppearance.AppCompat.Medium"
android:textColor="#color/white"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
/////POJO CLASS &json parsing & Adapter /////
public class ModelRouteDetailsUp {
String city_id;
String area_name;
String area_status;
String is_active;
String areas;
private ArrayList<ModelKidDetailsUp> kidlist;
///////this is the kid list
public ArrayList<ModelKidDetailsUp> getKidlist() {
return kidlist;
}
public void setKidlist(ArrayList<ModelKidDetailsUp> kidlist) {
this.kidlist = kidlist;
}
}
**///json parsing.......**
public boolean addRideDetails(JSONObject jsonObject) {
Boolean flag = false;
String isstatus = "";
if (jsonObject != null && jsonObject.length() > 0) {
try {
JSONArray mainArray = jsonObject.getJSONArray("schedules");
for (int i = 0; i < mainArray.length(); i++) {
ModelRouteDetailsUp modelRouteDetails = new ModelRouteDetailsUp();
JSONObject c = mainArray.getJSONObject(i);
////// For Route Details //////
JSONObject route_details = c.getJSONObject("route_details");
modelRouteDetails.setDs_id(route_details.optString("ds_id"));
modelRouteDetails.setDriver_id(route_details.optString("driver_id"));
modelRouteDetails.setTrip_id(route_details.optString("trip_id"));
modelRouteDetails.setRoute_id(route_details.optString("route_id"));
modelRouteDetails.setVehicle_id(route_details.optString("vehicle_id"));
modelRouteDetails.setStart_time(route_details.optString("start_time"));
modelRouteDetails.setEnd_time(route_details.optString("end_time"));
////// For Allotted Kids //////
JSONArray kidArray = c.getJSONArray("alloted_kids");
ArrayList<ModelKidDetailsUp> genre = new ArrayList<ModelKidDetailsUp>();
if (kidArray.length() > 0) {
for (int j = 0; j < kidArray.length(); j++) {
ModelKidDetailsUp kidDetailsUp = new ModelKidDetailsUp();
JSONObject kidObject = kidArray.getJSONObject(j);
kidDetailsUp.setKid_name(kidObject.getString("kid_name"));
kidDetailsUp.setKid_gender(kidObject.getString("kid_gender"));
kidDetailsUp.setKid_dob(kidObject.getString("kid_dob"));
kidDetailsUp.setKid_image(kidObject.getString("kid_image"));
genre.add(kidDetailsUp);
}
}
///////add the kidlist here
modelRouteDetails.setKidlist(genre);
////main array contains all the data i.e route details and kidlist for every row
KPHashmapUtils.m_ride_route_details_up.add(modelRouteDetails);
//}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return flag;
}
**/////adapter callfrom class**
private void showData() {
if (KPHashmapUtils.m_ride_route_details_up.size() > 0){
adapterTodayTrip = new AdapterTodayTrip(mContext, R.layout.list_item_todaytrip, KPHashmapUtils.m_ride_route_details_up, "TodayTrip",img_baseurl);
rv_trip_list.setAdapter(adapterTodayTrip);
}else {
tv_msg.setVisibility(View.VISIBLE);
}
}
Generally, the solution is to pass custom interface listener into the nested adapter and than the nested adapter will report any time one of his item clicked.
1.
You can create interface like:
public interface INestedClicked {
onNestedItemClicked(Drawable drawble)
}
2.
Pass in the constructor of SectionListDataAdapter a INestedClicked:
SectionListDataAdapter itemListDataAdapter = newSectionListDataAdapter(mContext, singleSectionItems, new INestedClicked() {
#Override
void onNestedItemClicked(Drawable drawble) {
// Do whatever you need after the click, you get the drawable here
}
});
In the constructor of SectionListDataAdapter save the instance of the listener as adapter parameter
private INestedClicked listener;
4.
When nested item clicked report the listener:
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
listener.onNestedItemClicked(imageView.getDrawable());
}
}

Android RecyclerView Adapter

what's the Wrong
this code for chat application .. messages not shown and ProgressDialog still in the screen
Adapter class
public class chatadaptor extends RecyclerView.Adapter<chatadaptor.MyViewHolder>{
private Context mContext;
private List<Message> messageList;
public chatadaptor(Context mContext, List<Message> messageList) {
this.mContext = mContext;
this.messageList = messageList;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView tv_time , tv_message_content;
RadioButton statusradiobutton ;
LinearLayout Rsenttext ,Rresecivedtext;
ImageView img_msg;
RelativeLayout Rsentpic ,Rresecivedp ;
public MyViewHolder(View view) {
super(view);
tv_time = (TextView) view.findViewById(R.id.tv_time);
tv_message_content = (TextView) view.findViewById(R.id.tv_message_content);
Rsenttext = (LinearLayout)view.findViewById(R.id.Rsenttext);
Rresecivedtext = (LinearLayout)view.findViewById(R.id.Rresecivedtext);
Rsentpic = (RelativeLayout)view.findViewById(R.id.Rsentpic);
Rresecivedp = (RelativeLayout)view.findViewById(R.id.Rresecivedp);
img_msg = (ImageView)view.findViewById(R.id.img_msg);
}
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View row = LayoutInflater.from(parent.getContext()).inflate(R.layout.chatting,parent,false);
MyViewHolder holder = new MyViewHolder(row);
return holder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
final Message message = messageList.get(position);
holder.Rresecivedtext.setVisibility(View.VISIBLE);
holder.tv_message_content.setText(message.getContent());
Toast.makeText(mContext,message.getDegree() , Toast.LENGTH_SHORT).show();
}
#Override
public int getItemCount() {
return messageList.size();
}
}
Xml file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
android:id="#+id/Rresecivedtext"
android:orientation="vertical">
<TextView
android:id="#+id/tv_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
android:layout_marginTop="2dp"
android:gravity="start"
android:paddingEnd="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="#string/app_name"
android:textColor="#color/colorPrimaryDark"
android:textSize="11sp" />
<FrameLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/tv_username"
android:layout_gravity="start"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
android:background="#drawable/received_message">
<TextView
android:id="#+id/tv_message_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="3dp"
android:gravity="center"
android:minWidth="60dp"
android:text=" مرحبا "
android:textColor="#color/album_title" />
</FrameLayout>
<TextView
android:id="#+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="#id/container"
android:layout_alignRight="#id/container"
android:layout_below="#+id/container"
android:layout_marginBottom="4dp"
android:layout_marginTop="1dp"
android:gravity="end"
android:paddingLeft="10dp"
android:text="12:20 AM"
android:textColor="#color/colorPrimary"
android:textSize="11sp" />
</RelativeLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="#+id/Rsenttext"
android:visibility="v"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/tv_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
android:layout_marginTop="2dp"
android:gravity="end"
android:paddingRight="10dp"
android:text="12:20 AM"
android:textSize="11sp" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginLeft="20dp"
android:layout_marginStart="20dp"
android:background="#drawable/sent_message">
<TextView
android:id="#+id/tv_message_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="2dp"
android:gravity="center"
android:minWidth="60dp"
android:text=" message text "
android:textColor="#color/white" />
</FrameLayout>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
And Activity
public void getMessages(){
progress=new ProgressDialog(this);
progress.setMessage(getResources().getString(R.string.wait));
progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progress.setIndeterminate(true);
progress.setCancelable(true);
progress.show();
final Thread t = new Thread() {
#Override
public void run() {
String ADD_TOKEN_URL = "http://XXXXXXXXX/api/Chat.php";
StringRequest request = new StringRequest(Request.Method.POST, ADD_TOKEN_URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if (response.trim().equals("1000")) {
Toast.makeText(userchats.this, "user error", Toast.LENGTH_SHORT).show();
progress.dismiss();
}else if (response.trim().equals("1111")){
Toast.makeText(userchats.this, "sending error", Toast.LENGTH_SHORT).show();
progress.dismiss();}
else {
response = response.substring(response.indexOf('\n')+1);
try {
String encodedstring = URLEncoder.encode(response, "ISO-8859-1");
response = URLDecoder.decode(encodedstring, "UTF-8");
} catch (UnsupportedEncodingException e) {
}
try {
List<Message> messageList = new ArrayList<>();
Message message;
JSONObject object = new JSONObject(response);
JSONArray apparray = object.getJSONArray("chat");
for (int i = 0; i < apparray.length(); i++) {
JSONObject currentobject = apparray.getJSONObject(i);
String type = currentobject.getString("type");
String content = currentobject.getString("content");
String timestamp = currentobject.getString("timestamp");
String degree = currentobject.getString("degree");
SharedPreferences pref = getSharedPreferences("MyAccount", 0); // 0 - for private mode
SharedPreferences.Editor editor = pref.edit();
String Uid = pref.getString("Uid", null); // getting String
message = new Message( Uid, type, content, timestamp, degree);
messageList.add(message);
chatadaptor adapter = new chatadaptor(userchats.this , messageList);
recyclerChat.setAdapter(adapter);
}
// progress.dismiss();
} catch (JSONException e) {
e.printStackTrace();
} }
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Toast.makeText(userchats.this, "error in sending message", Toast.LENGTH_SHORT).show(); progress.dismiss();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
SharedPreferences pref = getSharedPreferences("MyAccount", 0); // 0 - for private mode
SharedPreferences.Editor editor = pref.edit();
String Uid = pref.getString("Uid", null); // getting String
params.put("action","view");
params.put("userid",Uid);
//params.put("type",lpasss);
// params.put("content",lpasss);
// params.put("timestamp",lpasss);
return params;
}
};
Volley.newRequestQueue(getBaseContext()).add(request);
}
};
t.start();
}
data come from serve and converted to JSONObject enter code here correctly
what's the Wrong
this code for chat application .. messages not shown and ProgressDialog still in the screen
just add following lines because you did not add layout manager for your recyclerview
recyclerChat.setLayoutManager(new LinearLayoutManager(this));
hope this works for you..
public class ServicesListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Context con;
AtmHolder pvh1;
List<serviceListData> serviceslist;
public ServicesListAdapter(List<serviceListData> serviceslist, Context con) {
this.serviceslist = serviceslist;
this.con = con;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {
RecyclerView.ViewHolder viewHolder = null;
if (position == 0) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.services_list_item_style, viewGroup, false);
viewHolder = new AtmHolder(v);
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof AtmHolder) {
pvh1 = (AtmHolder) holder;
pvh1.tv_service.setText(serviceslist.get(position).getName());
Glide.with(con)
.load("image url")
.placeholder(R.drawable.internet)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(pvh1.iv_service);
}
}
public int getItemViewType(int position) {
int a = 0;
return a;
}
#Override
public int getItemCount() {
return serviceslist.size();
}
public static class AtmHolder extends RecyclerView.ViewHolder {
ImageView iv_service;
TextView tv_service;
AtmHolder(View itemView) {
super(itemView);
iv_service = (ImageView) itemView.findViewById(R.id.iv_service);
tv_service = (TextView) itemView.findViewById(R.id.tv_service);
}
}
}

Multiple radio-buttons in listview gets selected even if I select one button after scrolling

I have a list of cards-views which I am rendering, in each card there is information about that particular route and radio button which when clicked
should give me the position of the route form the complete list of routes
when clicked on different radio button previous one should be toggled and the one selected should be selected
Problem I am facing
when I select lets say 3rd radio button it selects 3rd items when the list renders the next views which is how the arrayadapter works. even though In my listview I have used android:choiceMode="singleChoice" still its not selecting single radio button.
Here is the image also go see what the problem is exactly
my RouteAdapter class whee I am trying to check which radio-button is pressed
class RouteAdapter extends ArrayAdapter<RouteItem> {
private Context mContext;
RouteAdapter(Activity context, List<RouteItem> routes) {
super(context, 0, routes);
this.mContext = context;
}
#NonNull
#Override
public View getView(final int position, final View convertView, #NonNull ViewGroup parent) {
View listItemView = convertView;
if(listItemView == null) {
// we are passing false as we don't want to attach it to view just yet,
// first set the proper name and details then set it.
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.route_view, parent, false);
}
// getting the route at that position
RouteItem route = getItem(position);
......
final RadioButton rb = (RadioButton) listItemView.findViewById(R.id.radio_button);
//todo: fix radio button to save prefs
rb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RouteItem route = getItem(position);
Log.d("RouteAdapter.class", "getView: "+ route.getRoute_id());
rb.toggle();
}
});
return listItemView;
}
}
my activity_view_route.xml where I am rendering all the routeItems
<?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">
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/add_route"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="true"
android:choiceMode="singleChoice"
tools:context="com.sjain.routeplanner.ViewRouteActivity" />
<TextView
android:id="#+id/empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textAppearance="?android:textAppearanceMedium" />
<ProgressBar
android:id="#+id/loading_indicator"
style="#style/Widget.AppCompat.ProgressBar"
android:indeterminateTint="#color/teal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
here is my route_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_centerHorizontal="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/route_name"
android:id="#+id/view_name"
android:textSize="20sp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="#string/endpoints"
android:id="#+id/view_start"
android:textSize="18sp"
android:layout_below="#id/view_name"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:text="#string/view_waypoints"
android:id="#+id/waypoints"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_below="#id/view_start"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="#string/endpoints"
android:id="#+id/view_end"
android:textSize="18sp"
android:layout_below="#id/waypoints"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/radio_button"
android:layout_alignParentEnd="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/view_map"
android:padding="8dp"
android:background="#color/com_facebook_blue"
android:layout_alignBottom="#id/view_end"
android:layout_alignParentEnd="true"
android:layout_marginEnd="7dp"
android:text="#string/view_map"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/view_id"
android:visibility="gone"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
My routeItem class
class RouteItem {
private String route_name;
private String start_point;
private String end_point;
private String route_id;
private ArrayList<String> waypoints;
private ArrayList<String> waypoint_name;
RouteItem(String route_name, String route_id, String start_point, String end_point, ArrayList<String> waypoints, ArrayList<String> waypoint_name) {
this.route_name = route_name;
this.route_id = route_id;
this.start_point = start_point;
this.end_point = end_point;
this.waypoints = waypoints;
this.waypoint_name = waypoint_name;
}
String getRoute_name() {
return route_name;
}
String getStart_point() {
return start_point.split(";")[0];
}
String getEnd_point() {
return end_point.split(";")[0];
}
String getEnd_point_coordinate() {
return end_point.split(";")[1];
}
String getStart_point_coordinate() {
return start_point.split(";")[1];
}
String getRoute_id() {
return route_id;
}
ArrayList<String> getWaypoints() {
return waypoints;
}
ArrayList<String> getWaypoint_name() {
return waypoint_name;
}
}
I know there is something like radio-group also but that seems to be out of option here since the list is generated dynamically depending on the number of routes obtained form the server. My problem is similar to this question Android Radio buttons in a custom listview changes its state when we scroll the list but this is also not properly answered.
If someone can please let me know how to fix this issue and just get the position of the card which is selected.
Ok. First of all change your RouteItem class as :
class RouteItem {
private String route_name;
private String start_point;
private String end_point;
private String route_id;
private ArrayList<String> waypoints;
private ArrayList<String> waypoint_name;
private String radioButtonState = "unSelected";
RouteItem(String route_name, String route_id, String start_point, String end_point, ArrayList<String> waypoints, ArrayList<String> waypoint_name) {
this.route_name = route_name;
this.route_id = route_id;
this.start_point = start_point;
this.end_point = end_point;
this.waypoints = waypoints;
this.waypoint_name = waypoint_name;
}
String getRoute_name() {
return route_name;
}
String getStart_point() {
return start_point.split(";")[0];
}
String getEnd_point() {
return end_point.split(";")[0];
}
String getEnd_point_coordinate() {
return end_point.split(";")[1];
}
String getStart_point_coordinate() {
return start_point.split(";")[1];
}
String getRoute_id() {
return route_id;
}
ArrayList<String> getWaypoints() {
return waypoints;
}
ArrayList<String> getWaypoint_name() {
return waypoint_name;
}
public String getRadioButtonState() {
return radioButtonState;
}
public void setRadioButtonState(String radioButtonState) {
this.radioButtonState = radioButtonState;
}
}
Now update your adapter.
class RouteAdapter extends ArrayAdapter<RouteItem> {
private Context mContext;
List<RouteItem> routes;
RouteAdapter(Activity context, List<RouteItem> routes) {
super(context, 0, routes);
this.mContext = context;
this.routes = routes;
}
#NonNull
#Override
public View getView(final int position, final View convertView, #NonNull ViewGroup parent) {
View listItemView = convertView;
if(listItemView == null) {
// we are passing false as we don't want to attach it to view just yet,
// first set the proper name and details then set it.
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.route_view, parent, false);
}
// getting the route at that position
RouteItem route = getItem(position);
......
final RadioButton rb = (RadioButton) listItemView.findViewById(R.id.radio_button);
//todo: fix radio button to save prefs
if(route.getRadioButtonState().equals("unSelected")){
rb.setSelected(false);
}
else{
rb.setSelected(true);
}
rb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RouteItem route = getItem(position);
Log.d("RouteAdapter.class", "getView: "+ route.getRoute_id());
rb.toggle();
if(rb.isSelected()){
route.setRadioButtonState("selected");
}
else {
route.setRadioButtonState("unSelected");
}
for(int i=0; i<routes.size(); i++){
if(i != position){
routes.get(i).setRadioButtonState("unSelected");
}
}
notifyDataSetChanged();
}
});
return listItemView;
}
}

Categories

Resources