I have an adapter linked to RecyclerView. I'm trying to implement chat screen, I use sockets to fetch messages, and if message came from user's phone chat bubble displays in left part of screen, if message came from interlocutor's phone chat bubble displays in left part of screen. Let's see:
Normal view:
And after when I open keyboard to type something, something goes wrong:
Opened keyboard:
But when I scroll RecyclerView up and down everything becomes ok.
Here is my codes:
Chat screen layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#F3F7FD">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_marginBottom="47dp"
android:paddingTop="6dp"
android:paddingBottom="8dp"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="#+id/element1"
android:layout_width="match_parent"
android:layout_height="47dp"
android:background="#FFFFFF"
android:orientation="horizontal"
android:layout_alignParentBottom="true">
<ImageView
android:id="#+id/sAttach"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_weight="0"
android:layout_marginTop="9dp"
android:layout_marginLeft="11dp"
android:layout_marginRight="9dp"
android:src="#drawable/attach"
android:tint="#A7A7A7"
android:background="?selectableItemBackgroundBorderless"
android:clickable="true" />
<ProgressBar
android:id="#+id/updateBar"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_weight="0"
android:layout_marginTop="9dp"
android:layout_marginLeft="11dp"
android:layout_marginRight="9dp"
android:indeterminate="true"
android:indeterminateTintMode="src_atop"
android:visibility="gone" />
<EditText
android:id="#+id/msg"
android:layout_width="match_parent"
android:layout_height="47dp"
android:layout_weight="1"
android:paddingLeft="2dp"
android:textSize="16sp"
android:inputType="textCapSentences"
android:maxLines="1"
android:hint="#string/hint_message"
android:background="#FFFFFF"/>
<ImageView
android:id="#+id/sBt"
android:layout_width="33dp"
android:layout_height="33dp"
android:layout_weight="0"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingLeft="9dp"
android:paddingRight="7dp"
android:layout_marginTop="7dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="10dp"
android:src="#drawable/send"
android:background="#drawable/circle_send_gray"
android:clickable="true" />
</LinearLayout>
<LinearLayout
android:id="#+id/element2"
android:layout_width="match_parent"
android:layout_height="47dp"
android:background="#FFFFFF"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:visibility="gone">
<TextView
android:id="#+id/blockMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginBottom="47dp"
android:layout_alignParentBottom="true"
android:orientation="vertical"
android:background="#20000000" />
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
Here is Chat.class:
private JsonArrayRequest getDataFromServer(String user, String room) {
//JsonArrayRequest of volley
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(HERE GOES MY APIS URL,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
//Calling method parseData to parse the json response
parseData(response);
//Hiding the progressbar
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//If an error occurs that means end of the list has reached
}
});
//Returning the request
return jsonArrayRequest;
}
private void parseData(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
//Creating the superhero object
ChatList superHero = new ChatList();
JSONObject json = null;
try {
//Getting json
json = array.getJSONObject(i);
superHero.setMessage(json.getString("message"));
superHero.setFromtype(json.getString("type"));
superHero.setPhoto(json.getString("photo"));
} catch (JSONException e) {
e.printStackTrace();
}
//Adding the superhero object to the list
listSuperHeroes.add(0, superHero);
}
recyclerView.scrollToPosition(listSuperHeroes.size() -1);
//Notifying the adapter that data has been added or changed
adapter.notifyDataSetChanged();
}
Chat Adapter:
public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ViewHolder> {
private Context context;
private float scale;
private int dpAsPixels;
private int dpAsPixels2;
private int dpAsPixels3;
private LinearLayout.LayoutParams params;
private LinearLayout.LayoutParams params2;
//List to store all superheroes
static List<ChatList> superHeroes;
public ChatAdapter(List<ChatList> superHeroes, Context context){
super();
//Getting all superheroes
this.superHeroes = superHeroes;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_list, parent, false);
ChatAdapter.ViewHolder viewHolder = new ViewHolder(v);
scale = context.getResources().getDisplayMetrics().density;
dpAsPixels = (int) (3 * scale + 0.5f);
dpAsPixels2 = (int) (12 * scale + 0.5f);
dpAsPixels3 = (int) (12 * scale + 0.5f)+180;
params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
return viewHolder;
}
#Override
public void onBindViewHolder(ChatAdapter.ViewHolder holder, int position) {
//Getting the particular item from the list
final ChatList superHero = superHeroes.get(position);
//Showing data on the views
if(superHero.getMessage().equals("image")) {
Picasso.with(context).load("http://mywebsite.com/uploads/media/"+superHero.getPhoto()).into(holder.photo);
holder.photo.setVisibility(ImageView.VISIBLE);
holder.message.setVisibility(TextView.GONE);
params2.bottomMargin = dpAsPixels+5;
params2.topMargin = dpAsPixels+5;
if(superHero.getFromtype().equals("he")) {
params.setMargins(dpAsPixels2, dpAsPixels, dpAsPixels3, dpAsPixels);
holder.photo.setLayoutParams(params2);
holder.photo.setBackgroundResource(R.drawable.chat_bubble_photo);
holder.textCard.setGravity(Gravity.LEFT);
}else{
params.setMargins(dpAsPixels3, dpAsPixels, dpAsPixels2, dpAsPixels);
holder.photo.setLayoutParams(params2);
holder.photo.setBackgroundResource(R.drawable.chat_bubble_me_photo);
holder.textCard.setGravity(Gravity.RIGHT);
}
holder.textCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
((Chat)context).openMedia(superHero.getPhoto());
}
});
}else{
holder.photo.setVisibility(ImageView.GONE);
holder.message.setVisibility(TextView.VISIBLE);
holder.message.setText(decodeMessage(superHero.getMessage()));
}
if(superHero.getFromtype().equals("he")) {
params.setMargins(dpAsPixels2, dpAsPixels, dpAsPixels3, dpAsPixels);
holder.message.setLayoutParams(params);
holder.message.setBackgroundResource(R.drawable.chat_bubble);
holder.message.setTextColor(context.getResources().getColor(R.color.darkgray));
holder.textCard.setGravity(Gravity.LEFT);
}else{
params.setMargins(dpAsPixels3, dpAsPixels, dpAsPixels2, dpAsPixels);
holder.message.setLayoutParams(params);
holder.message.setBackgroundResource(R.drawable.chat_bubble_me);
holder.message.setTextColor(context.getResources().getColor(R.color.colorPrimary));
holder.textCard.setGravity(Gravity.RIGHT);
}
}
public int getItemCount() {
return superHeroes.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
//Views
public TextView message;
public LinearLayout textCard;
public ImageView photo;
//Initializing Views
public ViewHolder(View itemView) {
super(itemView);
message = (TextView) itemView.findViewById(R.id.message);
textCard = (LinearLayout) itemView.findViewById(R.id.textCard);
photo = (ImageView) itemView.findViewById(R.id.photo);
}
}
private String decodeMessage(String message) {
String raz = URLDecoder.decode(message);
return StringEscapeUtils.unescapeJava(raz);
}
}
Sorry I cant able to comment thats why giving answer here
When you open keyboard at that time you have to scroll recyclerview at its last position.
mLinearLayoutManager.scrollToPosition(yourList.size());
Hope it works.
I've solved this problem this way:
I've add 2 different chat bubbles for both incoming and outgoing messages, and in ChatAdapter adjusted them by setVisibility to set which bubble should be shown. Margins are setted right in the layout file, not from ChatAdapter.
Related
I'm trying to put a RecyclerView inside a CardView and create items dynamically.
Obviously, in XML, RecyclerView is set inside CardView tag, but as you can see picture, RecyclerView item is created outside CardView.
(RecyclerView's items are the parts expressed as kg and set in the photo. And CardView is also an item of another RecyclerView.)
What's the problem?
XML
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="12dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
app:cardElevation="10dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/ll1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/workout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="TEST"/>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#color/light_blue_400"/>
</LinearLayout>
<LinearLayout
android:id="#+id/ll2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="#+id/ll1">
<com.google.android.material.button.MaterialButton
android:id="#+id/delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:layout_marginEnd="4dp"
style="#style/RoutineButtonStyle"
android:text="DELETE"
app:icon="#drawable/ic_delete"/>
<com.google.android.material.button.MaterialButton
android:id="#+id/add"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="4dp"
android:layout_marginEnd="8dp"
style="#style/RoutineButtonStyle"
android:text="ADD"
app:icon="#drawable/ic_add"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/ll2"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
Let me know if you need any other code.
Here is the Activity of your add/delete CardView:
//Item List if you want to add one or more Items
private List<MyItem> myItems = new ArrayList<>();
private Adapter smallCardAdapter;
private int size;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.rv);
//Creates a new Object in the Adapter.class
smallCardAdapter = new Adapter();
recyclerView.setAdapter(smallCardAdapter);
CardView cardView = findViewById(R.id.cardView);
MaterialButton delete = findViewById(R.id.delete);
MaterialButton add = findViewById(R.id.add);
//Add onClickListener
add.setOnClickListener(v -> {
try {
size = myItems.size();
//if the value is 0, a new item is created
//if you want to delete the card after 0 than you have to change the value to 0
if(size == 0){
//Creates a new Object in the MyItem.class
myItems.add(new MyItem("Set","1kg"));
}else{
MyItem myItem = myItems.get(0);
//Replace kg with "" to make a Integer
String secondString = myItem.getSecondString().replace("kg","");
Integer value = Integer.valueOf(secondString);
value++;
myItem.setSecondString(value+"kg");
myItems.set(0,myItem);
}
updateAdapter();
}catch (Exception e){
Log.w("MainActivity","Add Button OnClickListener");
e.printStackTrace();
}
});
//Delete onClickListener
delete.setOnClickListener(v->{
try {
size = myItems.size();
//If the value is 0 then canceled to avoid errors
if(size == 0){
return;
}
MyItem myItem = myItems.get(0);
//Replace kg with "" to make a Integer
String secondString = myItem.getSecondString().replace("kg","");
Integer value = Integer.valueOf(secondString);
//if the value is one or lower
if(value <= 1){
//The card will deleted after updateAdapter();
myItems.clear();
}else{
value--;
myItem.setSecondString(value+"kg");
myItems.set(0,myItem);
}
updateAdapter();
}catch (Exception e){
Log.w("MainActivity","Delete Button OnClickListener");
e.printStackTrace();
}
});
}
private void updateAdapter(){
try {
smallCardAdapter.setItems(myItems);
}catch (Exception e){
Log.w("MainActivity","updateAdapter");
e.printStackTrace();
}
}
The custom Item called MyItem:
public class MyItem {
String firstString;
String secondString;
public MyItem(String firstString,String secondString){
this.firstString = firstString;
this.secondString = secondString;
}
public String getFirstString() {
return firstString;
}
public void setFirstString(String firstString) {
this.firstString = firstString;
}
public String getSecondString() {
return secondString;
}
public void setSecondString(String secondString) {
this.secondString = secondString;
}
}
The Adapter.java creates a smallCard:
public class Adapter extends RecyclerView.Adapter<Adapter.SmallCardHolder> {
private List<MyItem> items = new ArrayList<>();
#NonNull
#Override
public SmallCardHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
// I created a new smallcard for the CardView
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.smallcard, parent, false);
SmallCardHolder smallCardHolder = new SmallCardHolder(itemView);
return smallCardHolder;
}
#Override
public void onBindViewHolder(#NonNull final SmallCardHolder holder, int position) {
//get the current item of the position
MyItem myItem = items.get(position);
String firstString = myItem.getFirstString();
String secondString = myItem.getSecondString();
holder.textViewSet.setText(firstString);
holder.textViewkg.setText(secondString);
}
#Override
public int getItemCount () {
return items.size();
}
public void setItems(List <MyItem> items) {
this.items = items;
notifyDataSetChanged();
}
class SmallCardHolder extends RecyclerView.ViewHolder {
//Here are the TextView's of the smallcard (smallcard.xml)
private TextView textViewSet;
private TextView textViewkg;
public SmallCardHolder(#NonNull View itemView) {
super(itemView);
textViewSet = itemView.findViewById(R.id.set);
textViewkg = itemView.findViewById(R.id.kg);
}
}
}
Create a new layout with name called smallcard.xml for the Adapter.java:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/set"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Set"
android:layout_centerVertical="true"
android:textSize="18sp"
android:layout_marginStart="5dp"
android:textColor="?attr/colorPrimary"
android:textStyle="bold"/>
<TextView
android:id="#+id/kg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="kg"
android:layout_toRightOf="#id/set"
android:layout_marginLeft="55dp"
android:layout_centerVertical="true"
android:textColor="?attr/colorPrimary"
android:textSize="16sp"
android:layout_marginRight="10dp"
android:maxLines="1"/>
</RelativeLayout>
</RelativeLayout>
In your XML you have to give the CardView a name. I called it cardView. Here is the code android:id="#+id/cardView"
Result:
You will find more information as comments in the code.
Child RecyclerView inside Parent RecyclerView is showing at End of Parent RecyclerView ?
I Want To Show Categroy in Parent RecyclerView & show its Sub Category in Child RecyclerView
But When I Click Parent RecyclerView To Show That Sub Category the Child RecyclerView is showing at The Full End Of Parent Category Please Check Where Is I'm Wrong?
Here is My Results:
First Item Clicked
.
Second Item Clicked
My Code:
This Is My Main Layout:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".USER.Category">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Category"/>
</LinearLayout>
This is my Main java File:
public class Category extends AppCompatActivity {
static Toast Toasts;
RecyclerView Category;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category);
Category = findViewById(R.id.Category);
Category.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
Category_View_request();
}
public void Category_View_request() {
RequestQueue requestQueue = Volley.newRequestQueue(Category.this);
String url = Constant.Category;
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
GridView_listItems[] Category_View_response = gson.fromJson(response, GridView_listItems[].class);
Category.setAdapter(new CategoryView_Adapter(Category.this, Category_View_response));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toasts = Toast.makeText(Category.this, "ERROR: Please Check Internet & Try Again", Toast.LENGTH_SHORT);
Toasts.show();
}
});
requestQueue.add(stringRequest);
}
}
this is Parent Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_gravity="center"
android:orientation="vertical"
android:padding="5dp"
android:id="#+id/layout">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="120dp"
android:id="#+id/nameLayout">
<ImageView
android:id="#+id/categoryimage"
android:layout_width="120dp"
android:layout_height="120dp"
android:adjustViewBounds="true"
android:background="#fff"
android:contentDescription="#string/todo"
android:padding="8dp"
android:scaleType="fitXY" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal"
android:paddingLeft="8dp"
android:paddingTop="8dp"
android:paddingRight="8dp"
android:paddingBottom="8dp">
<Space
android:layout_width="112dp"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="8dp"
android:paddingTop="8dp"
android:paddingRight="8dp"
android:paddingBottom="8dp">
<TextView
android:id="#+id/categoryname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="1dp"
android:singleLine="true"
android:text="#string/test_product_name"
android:textColor="#color/Black"
android:textSize="13sp"
tools:ignore="RtlSymmetry" />
<TextView
android:id="#+id/categorydec"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="1dp"
android:paddingTop="3dp"
android:singleLine="true"
android:text="#string/test_product_description"
android:textColor="#color/common_google_signin_btn_text_light_default"
android:textSize="12sp"
tools:ignore="RtlSymmetry" />
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/click">
</RelativeLayout>
</RelativeLayout>
<androidx.cardview.widget.CardView
android:id="#+id/subview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:background="#color/White"
android:elevation="8dp"
android:paddingTop="10dp"
>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/subCatview"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</androidx.cardview.widget.CardView>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
This is Parent Adapter:
public class CategoryView_Adapter extends RecyclerView.Adapter<CategoryView_Adapter.CategoryViewHolder> {
Toast Toasts;
private static Context context;
private static GridView_listItems[] data;
public CategoryView_Adapter(Context context, GridView_listItems[] data) {
this.context = context;
this.data = data;
}
#NonNull
#Override
public CategoryViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.category_view, parent, false);
return new CategoryViewHolder(view);
}
#SuppressLint("SetTextI18n")
#Override
public void onBindViewHolder(#NonNull final CategoryViewHolder holder, int position) {
final GridView_listItems CategoryList = data[position];
holder.categoryname.setText(CategoryList.getName());
holder.categorydec.setText(CategoryList.getId());
Glide.with(holder.categoryimage.getContext())
.applyDefaultRequestOptions(new RequestOptions()
.placeholder(R.drawable.product_loading)
.error(R.drawable.product_loading_failed))
.load(Constant.MAINImagUrl + CategoryList.getCategoryLogo().substring(2))
.into(holder.categoryimage);
holder.categoryname.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.layout.setBackgroundColor(ContextCompat.getColor(context, R.color.common_google_signin_btn_text_light_default));
Grid_View_request(CategoryList.getName());
}
});
}
#Override
public int getItemCount() {
return data.length;
}
public static class CategoryViewHolder extends RecyclerView.ViewHolder {
ImageView categoryimage;
TextView categoryname, categorydec;
CardView subview;
RelativeLayout click;
LinearLayout layout;
public static RecyclerView subCatview;
public CategoryViewHolder(#NonNull View itemView) {
super(itemView);
categoryimage = (ImageView) itemView.findViewById(R.id.categoryimage);
categoryname = (TextView) itemView.findViewById(R.id.categoryname);
categorydec = (TextView) itemView.findViewById(R.id.categorydec);
click = (RelativeLayout) itemView.findViewById(R.id.click);
subview = (CardView) itemView.findViewById(R.id.subview);
layout = (LinearLayout) itemView.findViewById(R.id.layout);
subCatview = (RecyclerView) itemView.findViewById(R.id.subCatview);
GridLayoutManager gridLayoutManager = new GridLayoutManager(MyApplication.getAppContext(), 3, GridLayoutManager.VERTICAL, false);
subCatview.setLayoutManager(gridLayoutManager);
}
}
public static void Grid_View_request(final String category) {
RequestQueue requestQueue = Volley.newRequestQueue(MyApplication.getAppContext());
String url = Constant.Sub_Category;
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if (response.contains("CityGroceryEmptyResponse")) {
Toast.makeText(MyApplication.getAppContext(), "No Sub Category Found", Toast.LENGTH_SHORT).show();
} else {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
Sub_Category_list[] Sub_Category_list = gson.fromJson(response, Sub_Category_list[].class);
subCatview.setAdapter(new Sub_Category_Adapter(MyApplication.getAppContext(), Sub_Category_list));
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MyApplication.getAppContext(), "ERROR: Please Check Internet & Try Again", Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("category", category);
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/x-www-form-urlencoded");
return params;
}
};
requestQueue.add(stringRequest);
}
}
This is My Child Layout:
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_gravity="center"
android:layout_margin="2dp"
android:orientation="horizontal"
android:elevation="8dp"
app:cardCornerRadius="1dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:paddingLeft="8dp"
android:paddingTop="8dp"
android:paddingRight="8dp"
android:paddingBottom="8dp">
<ImageView
android:id="#+id/subCatNameimage"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#mipmap/ic_launcher" />
<TextView
android:id="#+id/subCatName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/subCatNameimage"
android:layout_marginTop="4dp"
android:gravity="center"
android:maxLength="30"
android:text="menu name"
android:textColor="#color/colorPrimary"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/subCatNameimage" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
This is My Child Adapter:
public class Sub_Category_Adapter extends RecyclerView.Adapter<Sub_Category_Adapter.CategoryViewHolder> {
Toast Toasts;
private static Context context;
private static Sub_Category_list[] data;
public Sub_Category_Adapter(Context context, Sub_Category_list[] data) {
this.context = context;
this.data = data;
final Sub_Category_list SubCategoryList = data[0];
}
#NonNull
#Override
public CategoryViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.gridview_items, parent, false);
return new CategoryViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final CategoryViewHolder holder, final int position) {
final Sub_Category_list SubCategoryList = data[position];
holder.subCatName.setText(SubCategoryList.getSubCategoryName());
Glide.with(holder.subCatNameimage.getContext())
.applyDefaultRequestOptions(new RequestOptions()
.placeholder(R.drawable.product_loading)
.error(R.drawable.product_loading_failed))
.load(Constant.MAINImagUrl + SubCategoryList.getSubCategoryLogo().substring(2))
.into(holder.subCatNameimage);
}
#Override
public int getItemCount() {
return data.length;
}
public static class CategoryViewHolder extends RecyclerView.ViewHolder {
ImageView subCatNameimage;
TextView subCatName;
public CategoryViewHolder(#NonNull View itemView) {
super(itemView);
subCatName = (TextView) itemView.findViewById(R.id.subCatName);
subCatNameimage = (ImageView) itemView.findViewById(R.id.subCatNameimage);
}
}
}
Please Correct Me Where is doing Mistake
Thanks In Advance
You can achieve that requirement by using an expandable recycler view.
There are a lot of libraries you can use to achieve this.
You can use this library.
Or follow this post to achieve this on your own, you might need to make some changes to get the output as per your requirement.
I'am achieve My requirement by using an expandable recycler view
HERE
The Data from the web service is received properly, I got it checked by printing all the value in Log, so obviously there is no error from my back-end service. The data is also occupying blank space as per the array size of my list in layout, but i cannot see the data, only white screen with the TextView. There are no errors in the LogCat. I don't know what i did wrong, little help would be appreciated. Thanks
This is my MainActivity which has AsyncTask to fetch the Data.
swaop=(SwipeRefreshLayout)contentview.findViewById(R.id.layout_offerproducts);
rvofferproducts = (RecyclerView)findViewById(R.id.rv_offerproducts);
oparraylist = new ArrayList<B_OfferProducts>();
opadapter = new adapter_offerproducts(getApplicationContext(), oparraylist);
final RecyclerView.LayoutManager manager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
rvofferproducts.setLayoutManager(manager);
rvofferproducts.setItemAnimator(new DefaultItemAnimator());
rvofferproducts.setAdapter(opadapter);
isConnected = ConnectivityReceiver.isConnected();
if(isConnected)
{
new loadallofferproducts().execute();
}
//ASYNC TASK
public class loadallofferproducts extends AsyncTask<String, String, String>
{
#Override
protected String doInBackground(String... strings) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("OfferID", OfferID));
JSONObject jsonObject = jsonParser.makeHttpRequest(url_offerproducts, "POST", params);
try {
int success = jsonObject.getInt("success");
if(success == 1)
{
ophasharraylist = new ArrayList<HashMap<String, String>>();
offerproductsarray = jsonObject.getJSONArray("offerproducts");
for(int i = 0; i < offerproductsarray.length(); i++)
{
JSONObject opobj =offerproductsarray.getJSONObject(i);
String ProductId = opobj.getString("ProductID");
String ProductName = opobj.getString("ProductName");
String ProductPrice = "₹ " + opobj.getString("ProductPrice");
String ProductDP = "₹ " +opobj.getString("ProductDiscountP");
String ProductURL = opobj.getString("ProductPicURL");
String ProductDescription = opobj.getString("ProductDescription");
HashMap<String, String> map = new HashMap<String, String>();
B_OfferProducts b_offerProducts = new B_OfferProducts();
map.put("ProductID", ProductId);
map.put("ProductName", ProductName);
map.put("ProductPrice", ProductPrice);
map.put("ProductDiscountP", ProductDP);
map.put("ProductPicURL",ProductURL);
map.put("ProductDescription", ProductDescription);
ophasharraylist.add(map);
b_offerProducts.setProductPicURL(ophasharraylist.get(i).get("ProductPicURL").trim());
b_offerProducts.setProductName(ophasharraylist.get(i).get("ProductName").trim());
b_offerProducts.setProductPrice(ophasharraylist.get(i).get("ProductPrice").trim());
b_offerProducts.setProductDiscountP(ophasharraylist.get(i).get("ProductDiscountP").trim());
b_offerProducts.setProductDescription(ophasharraylist.get(i).get("ProductDescription").trim());
Log.d("OfferProducts",b_offerProducts.getProductName());
oparraylist.add(b_offerProducts);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
opadapter.notifyDataSetChanged();
}
}
}
This is My Adapter class.
public class adapter_offerproducts extends RecyclerView.Adapter<adapter_offerproducts.MyViewHolder>{
private List<B_OfferProducts> offerproductlist;
Context mcontext;
public class MyViewHolder extends RecyclerView.ViewHolder
{
public TextView pname, pprice, pdpricce, pdescription;
public ImageView pimg;
public MyViewHolder(View view)
{
super(view);
pname = (TextView)view.findViewById(R.id.rv_op_pname);
pprice = (TextView)view.findViewById(R.id.rv_op_pprice);
pdpricce = (TextView)view.findViewById(R.id.rv_op_pdprice);
pdescription = (TextView)view.findViewById(R.id.rv_op_pdescription);
pimg = (ImageView)view.findViewById(R.id.rv_op_img);
}
}
public adapter_offerproducts(Context context, List<B_OfferProducts> oplist )
{
mcontext = context;
this.offerproductlist = oplist;
}
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemview = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_container_offerproducts,parent,false);
return new MyViewHolder(itemview);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
B_OfferProducts b_offerProducts = new B_OfferProducts();
Picasso.get()
.load(b_offerProducts.getProductPicURL())
.into(holder.pimg);
holder.pname.setText(b_offerProducts.getProductName());
holder.pprice.setText(b_offerProducts.getProductPrice());
holder.pdpricce.setText(b_offerProducts.getProductDiscountP());
holder.pdescription.setText(b_offerProducts.getProductDescription());
}
#Override
public int getItemCount() {
return offerproductlist.size();
}
}
This is My Container for RecyclerView
<?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">
<ImageView
android:layout_width="150dp"
android:layout_height="150dp"
android:id="#+id/rv_op_img"
android:contentDescription="ProductImage"/>
<TextView
android:id="#+id/rv_op_pname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="TextView"
app:layout_constraintStart_toEndOf="#+id/rv_op_img"
tools:layout_editor_absoluteY="16dp" />
<TextView
android:id="#+id/rv_op_pprice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="TextView"
app:layout_constraintStart_toEndOf="#+id/rv_op_img"
tools:layout_editor_absoluteY="56dp" />
<TextView
android:id="#+id/rv_op_pdprice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="TextView"
app:layout_constraintStart_toEndOf="#+id/rv_op_img"
tools:layout_editor_absoluteY="96dp" />
<TextView
android:id="#+id/rv_op_pdescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="TextView"
app:layout_constraintStart_toEndOf="#+id/rv_op_img"
tools:layout_editor_absoluteY="131dp" />
</android.support.constraint.ConstraintLayout>
This is My Activity Layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
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"
android:id="#+id/layout_offerproducts"
tools:context="com.test.OfferProducts">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_marginTop="60dp"
android:layout_gravity="center"
android:layout_height="wrap_content"
android:orientation="vertical" >
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/rv_offerproducts">
</android.support.v7.widget.RecyclerView>
<TextView
android:id="#+id/textView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Blah This IS TEXT" />
</LinearLayout>
</ScrollView>
You probably should be getting your B_OfferProducts from list passed to adapter, that is from List offerproductlist, instead of creating an object every time.
Regardless of what you put in the constructor of B_OfferProducts class, your items will not be bind to the list, which is probably the reason why data is not loading correctly. These objects created will live only inside ViewHolder.
This means that you should replace
B_OfferProducts b_offerProducts = new B_OfferProducts();
in onBindViewHolder() with getting the object relevant to the current postion in the list, so like this:
B_OfferProducts b_offerProducts = offerproductlist.get(position)
I hope it helps. Cheers!
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);
}
}
}
I'm trying to implement recycler view in my android app. The data to be shown is got from a server, the data includes a timestamp that should also be displayed.
The code that is setting up the data with the recycler view is as follows:
try{
JSONArray jsonArray = new JSONArray(response);
if(jsonArray.length()!=0) {
TimeStamp = new String[jsonArray.length()];
for(int i=0;i<jsonArray.length();i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
TimeStamp[i] = jsonObject.getString("TimeStamp1");
int ij = TimeStamp[i].indexOf('T');
String s = TimeStamp[i].substring(0,ij-1);
String s2 = TimeStamp[i].substring(ij+1,TimeStamp[i].length()-1);
sb.append(s+"\n"+s2+"\n");
String mod = s+"\n"+s2+"\n";
dataset.add(new DataEntryModel(1,mod,10,1));
}
CustomAdapter myAdapter = new CustomAdapter(dataset);
recyclerView.setAdapter(myAdapter);
resultView.setText(sb.toString());
}else{
}
}catch (Exception e){
sb.append(e.toString());
resultView.setText(sb.toString());
}
As you can see from the screenshot for some reason the recycler view is not displaying the full string. I displayed the string in a textview above the button. That seems to be working fine. What is causing the recycler view to not render the items properly. If I try to render s2 first then the time until the the second : is displayed.
The layout for the card :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="#+id/card_view"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:clickable="true"
card_view:cardElevation="1dp"
card_view:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/textBlack"
android:text="UserName"
android:id="#+id/userNametext"
android:layout_alignBaseline="#+id/userName"
android:layout_alignBottom="#+id/userName"
android:layout_alignParentStart="true"
android:layout_marginStart="15dp" />
<TextView
android:text="Loc of userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="75dp"
android:textColor="#color/textBlack"
android:id="#+id/userName"
android:layout_toLeftOf="#+id/userNametext"
android:layout_marginTop="8dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true" />
<TextView
android:text="Time Of Entry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/Time_of_Entry"
android:layout_marginStart="15dp"
android:textColor="#color/textBlack"
android:layout_below="#+id/textView"
android:layout_alignStart="#+id/textView"
android:layout_marginTop="50dp" />
<TextView
android:text="Loc of Time"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:textColor="#color/textBlack"
android:id="#+id/timestamp_of_user"
android:layout_alignBaseline="#+id/Time_of_Entry"
android:layout_alignBottom="#+id/Time_of_Entry"
android:layout_alignStart="#+id/userName"
android:layout_marginStart="14dp" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
The adapter for the recycler view is
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
ArrayList<DataEntryModel> dataSet;
CardView cards;
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView UserName, TimeStamp;
public MyViewHolder(View itemView){
super(itemView);
this.UserName = (TextView)itemView.findViewById(R.id.userName);
TimeStamp = (TextView)itemView.findViewById(R.id.timestamp_of_user);
cards = (CardView)itemView.findViewById(R.id.card_view);
}
#Override
public void onClick(View view) {
}
}
public CustomAdapter(ArrayList<DataEntryModel> data){
dataSet = data;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_fragment,parent,false);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
TextView userName = holder.UserName;
TextView TimeStamp = holder.TimeStamp;
userName.setText(SingletonDataClass.SharedPrefsUserNameForSession);
TimeStamp.setText(dataSet.get(position).getTimeStamp());
}
#Override
public int getItemCount() {
return dataSet.size();
}
}
What is the reason for this odd behavior of the recycler view? How can I fix this problem?