ViewPager2 Adapter is being called Twice - android

I am starting with Android java development and I am facing a issue on the ViewPager2 implementation.
On my app I have a ViewPager2 and I am inflate on it a layout which has a RecycleView.
The problem is, when I turn the ViewPager2 from page 0 to page 1, the adapter execulte onBindViewHolder twice, jumping from adapter position 0 to 1 and imediatelly from position 1 to 2. (ViewPager2 position stay on 1)
As I am populating the RecycleView with a Volley DB consult, this theard start only after the ViewPAger2 Adapter finish its works (after adapter execulte onBindViewHolder twice). So, only the ViewPager2 position 2 is populated (twice), ViewPager2 page 1 stay empty.
Thus, I kindly ask your help to avoid adapter execute onBindViewHolder twice once ViewPAger2 change. Or makes Volley executes its thread when the adapter position change from 0 to 1 and again when it change from 1 to 2.
Please help me since I have 5 days working around this problem without success.
See belwo my codes:
MY VIEWPAGER2 ADAPTER (Adapter_Department)
package br.com.portosaue.portosaueapp;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class Adapter_Department extends RecyclerView.Adapter<Adapter_Department.UserViewHolder> {
Context mContext;
private RecyclerView rcv_products;
private RecyclerView.Adapter mAdapter;
private LinearLayoutManager mLayoutManager;
ViewPager2 vpg_productList;
List<Department> departmentList;
String Host_IP;
String ProductComment;
public MyAdapter(Context mContext, List<Department> departmentList) {
this.mContext = mContext;
this.departmentList = departmentList;
}
#NonNull
#Override
public UserViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Host_IP = "192.168.0.100";
View view = LayoutInflater.from(mContext).inflate(R.layout.products_list, parent, false);
return new UserViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull UserViewHolder holder, int position) {
productsList(departmentList.get(position).getName());
}
#Override
public int getItemCount() {
return departmentList.size();
}
public class UserViewHolder extends RecyclerView.ViewHolder {
public UserViewHolder(#NonNull final View itemView) {
super(itemView);
rcv_products = itemView.findViewById(R.id.rcv_Products);
vpg_productList = ((Activity) mContext).findViewById(R.id.vpg_Products);
}
}
private void productsList(String department){
//SELECTING URL
String json_products;
switch (department) {
case "Salao":
json_products = "http://" + Host_IP + "/getSalon.php";
break;
case "Cozinha":
json_products = "http://" + Host_IP + "/getKitchen.php";
break;
case "Copa":
json_products = "http://" + Host_IP + "/getDrink.php";
break;
case "Churrasqueira":
json_products = "http://" + Host_IP + "/getBarbecue.php";
break;
case "Caixa":
json_products = "http://" + Host_IP + "/getCash.php";
break;
default:
json_products = "http://" + Host_IP + "/getProducts";
}
//VOLLEY / FETCH / JSONOBJECT
StringRequest stringRequest = new StringRequest(Request.Method.GET, json_products,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
//converting the string to json array object
JSONArray array = new JSONArray(response);
ArrayList<Func_LoadProduct> loadproduct = new ArrayList<Func_LoadProduct>();
Func_LoadProduct p;
String ImagePath;
//traversing through all the object
for (int i = 0; i < array.length(); i++) {
//getting product object from json array
JSONObject product = array.getJSONObject(i);
//adding the product to product list
ImagePath = "http://" + Host_IP + "/PS APP Images/" + product.getString("Imagem");
p = new Func_LoadProduct(product.getInt("ID"),
product.getString("Nome"),
product.getDouble("Preco"),
ImagePath,
"");
loadproduct.add(p);
}
rcv_products=((Activity)mContext).findViewById(R.id.rcv_Products);
rcv_products.setHasFixedSize(true);
mLayoutManager=new LinearLayoutManager(mContext);
mAdapter=new Adapter_Products(loadproduct);
rcv_products.setLayoutManager(mLayoutManager);
rcv_products.setAdapter(mAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Volley.newRequestQueue(mContext).add(stringRequest);
}
}
VIEWPAGER2 CLASS (Products)
package br.com.portosaue.portosaueapp;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.viewpager2.widget.ViewPager2;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class Products extends AppCompatActivity {
ViewPager2 vpg_products;
List<Department> departmentList;
Adapter_Department adapterDepartment;
String TableNumb;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_products);
vpg_products = findViewById(R.id.vpg_Products);
departmentList = new ArrayList<>();
departmentList.add(new Department("Salon"));
departmentList.add(new Department("Kitchen"));
departmentList.add(new Department("Bar"));
adapterDepartment = new Adapter_Department(this, departmentList);
vpg_products.setAdapter(adapterDepartment);
}
}
VIEWPAGER2 LAYOUT (activity_departments.xml)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Products"
android:orientation="vertical">
<include
android:id="#+id/tbr_toobar"
layout = "#layout/toolbar"/>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/vpg_Products"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="#+id/tbr_toobar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tbr_toobar"
app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
RECYCLEVIEW ADAPTER (Adapter_Products)
package br.com.portosaue.portosaueapp;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class Adapter_Products extends RecyclerView.Adapter<Adapter_Products.MyViewHolder>{
private ArrayList<Func_LoadProduct> mProductList;
public static class MyViewHolder extends RecyclerView.ViewHolder {
public ImageView img_ProductImage;
public TextView txv_ProductName;
public TextView txv_ProductPrice;
public TextView txv_ProductID;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
img_ProductImage = itemView.findViewById(R.id.imv_ProductImage);
txv_ProductName = itemView.findViewById(R.id.txv_ProductName);
txv_ProductPrice = itemView.findViewById(R.id.txv_ProductPrice);
txv_ProductID = itemView.findViewById(R.id.txv_ProcutID);
}
}
public Adapter_Products( ArrayList<Func_LoadProduct> productList){
this.mProductList=productList;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_line, parent, false);
MyViewHolder evh = new MyViewHolder(v);
return evh;
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
Func_LoadProduct currentItem = mProductList.get(position);
Picasso.get().load(mProductList.get(position).getProductImageName()).into(holder.img_ProductImage);
holder.txv_ProductName.setText(currentItem.getProductName());
holder.txv_ProductPrice.setText("R$ " + Double.toString(currentItem.getProductPrice()));
holder.txv_ProductID.setText("ID: " + Integer.toString(currentItem.getProductID()));
}
#Override
public int getItemCount() {
return mProductList.size();
}
}
RECYCLEVIEW LAYOUT (product_list.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rcv_Products"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp" />
</RelativeLayout>
ITEMS CLASS (Func_LoadProduct)
package br.com.portosaue.portosaueapp;
public class Func_LoadProduct {
private int ProductID;
private String ProductName;
private double ProductPrice;
private String ProductImageName;
private String ProductComment;
public Func_LoadProduct(int productID, String productName, double productPrice, String productImageName, String productComment){
this.ProductID = productID;
this.ProductName = productName;
this.ProductPrice = productPrice;
this.ProductImageName = productImageName;
this.ProductComment = productComment;
}
//SET
public void setProductID(int productID) {
this.ProductID = productID;
}
public void setProductName(String productName) {
this.ProductName = productName;
}
public void setProductPrice(double productPrice) {
this.ProductPrice = productPrice;
}
public void setProductImageName(String productImageName) { this.ProductImageName = productImageName; }
public void setProductComment(String productComment) { this.ProductComment = productComment; }
//GET
public int getProductID() {
return this.ProductID;
}
public String getProductName() {
return this.ProductName;
}
public double getProductPrice() {
return this.ProductPrice;
}
public String getProductImageName() { return this.ProductImageName; }
public String getProductComment() { return this.ProductComment; }
}
ITEMS LAYOUT (product_line.xml)
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
app:cardCornerRadius="4dp"
android:layout_marginTop="2dp"
android:layout_marginBottom="2dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp">
<ImageView
android:id="#+id/imv_ProductImage"
android:layout_width="60dp"
android:layout_height="60dp"
android:padding="2dp"
android:scaleType="fitXY"
tools:srcCompat="#tools:sample/avatars"/>
<TextView
android:id="#+id/txv_ProductName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="64dp"
android:layout_marginTop="2dp"
android:textColor="#android:color/black"
android:textSize="20sp"
android:layout_weight="10"
android:text="Produto"
android:textAppearance="#style/TextAppearance.AppCompat.Large"/>
<TextView
android:id="#+id/txv_ProductPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/txv_ProductName"
android:layout_alignParentTop="true"
android:layout_marginStart="2dp"
android:layout_marginTop="31dp"
android:layout_weight="3"
android:text="Valor"
android:textSize="15sp" />
<TextView
android:id="#+id/txv_ProcutID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/txv_ProductPrice"
android:layout_alignParentStart="true"
android:layout_marginStart="347dp"
android:layout_marginBottom="0dp"
android:layout_weight="1"
android:text="ID"
android:textSize="15sp" />
</RelativeLayout>
</androidx.cardview.widget.CardView>

Related

Getting error while setting a data into recycler view

I am getting 2 data from firebase and setting them in a card view in recycler view they are
name
nodename
there is no problem with the "name" data but my "nodename" data is not being set in the text view
the error message that I am getting
No setter/field for node found on class com.Loopchat.com.Mychats_Model
my model class
package com.Loopchat.com;
public class Mychats_Model {
public Mychats_Model(String name, String nodename) {
this.name = name;
this.nodename = nodename;
}
Mychats_Model(){
}
String name, nodename;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNodename() {
return nodename;
}
public void setNodename(String nodename) {
this.nodename = nodename;
}
}
this is my Firebase data base structure
myAdapter Class
package com.Loopchat.com;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
public class Mychats_Adapter extends
FirebaseRecyclerAdapter<Mychats_Model,Mychats_Adapter.myViewHolder> {
private static final int MSG_TYPE_LEFT = 0;
private static final int MSG_TYPR_RIGHT = 1;
/**
* Initialize a {#link RecyclerView.Adapter} that listns to a Firebae query. See
* {#link FirebaseRecyclerOptions} for configuration options.
*
* #param options
*/
public Mychats_Adapter(#NonNull FirebaseRecyclerOptions<Mychats_Model> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull myViewHolder holder, int position, #NonNull Mychats_Model model) {
holder.name.setText(model.getName());
holder.node.setText(model.getNodename());
holder.name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(holder.node.getContext(),Chat2.class);
intent.putExtra("nodename",model.getNodename());
holder.node.getContext().startActivity(intent);
}
});
}
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.mychats_item, parent, false);
return new myViewHolder(view);
// if (viewType == MSG_TYPE_LEFT) {
// View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_left, parent, false);
// return new myViewHolder(view);
//} else {
// View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_item, parent, false);
// return new myViewHolder(view);
//}
}
class myViewHolder extends RecyclerView.ViewHolder {
TextView name,node;
public myViewHolder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.namedoc);
// node = itemView.findViewById(R.id.nodename);
node = itemView.findViewById(R.id.d);
}
}
}
XML of my item for my recycler view
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="3dp"
app:cardUseCompatPadding="true"
android:elevation="6dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="#+id/imagedic"
android:src="#mipmap/ic_launcher"
android:layout_centerVertical="true">
</ImageView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/imagedic"
android:text="Username"
android:id="#+id/namedoc"
android:textSize="30dp"
android:layout_marginStart="20dp"
android:textStyle="bold"/>
<TextView
android:id="#+id/d"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/namedoc"
android:layout_marginStart="20dp"
android:layout_marginLeft="98dp"
android:layout_marginTop="4dp"
android:layout_toRightOf="#+id/imagedic"
android:text="Nodename"
android:textSize="15dp" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
my MainActivity
package com.Loopchat.com;
import static android.content.ContentValues.TAG;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.FirebaseDatabase;
public class MyChats extends AppCompatActivity {
RecyclerView rvc ;
Mychats_Adapter mychats_adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_chats);
SharedPreferences sharedPreferences = getSharedPreferences("MySharedPref",MODE_PRIVATE);
String myname = sharedPreferences.getString("username", "User");
Toast.makeText(this, myname, Toast.LENGTH_SHORT).show();
Log.d("TAG", "onCreate: "+myname+"Chats");
rvc = findViewById(R.id.rvc);
rvc.setLayoutManager(new LinearLayoutManager(this));
FirebaseRecyclerOptions<Mychats_Model> options =
new FirebaseRecyclerOptions.Builder<Mychats_Model>() .setQuery(FirebaseDatabase.getInstance().getReference().child(myname+"Chats"), Mychats_Model.class)
.build();
mychats_adapter = new Mychats_Adapter(options);
rvc.setAdapter(mychats_adapter);
}
#Override
protected void onStart() {
super.onStart();
mychats_adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
mychats_adapter.stopListening();
}
}

App crashes on attaching fetched data from Retrofit to adapter

I am working with Retrofit. I followed a tutorial and did exactly what he said. Response is working perfectly in a single TextView but not in RecyclerView. When I added an adapter class, it start crashing. I read logcat file too but didn't seem helpful. The app crashes without showing any error or exception.
Here is my main XML class with a RecyclerView.
<?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=".MainActivity"
android:orientation="vertical">
<!-- <ScrollView-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent">-->
<!-- <TextView-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:id="#+id/text1"-->
<!-- android:layout_marginTop="5dp"-->
<!-- android:layout_marginStart="2dp">-->
<!-- </TextView>-->
<!-- </ScrollView>-->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
My main class is working fine with a for loop to print data in one TextView but not for adapter or RecyclerView.
package com.example.apipractice;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
public class MainActivity extends AppCompatActivity {
apiInterface instanceforAPI;
LinearLayoutManager linearLayoutManager;
//TextView txt;
RecyclerView recview;
adapter ad;
List<jsonData> data = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//txt = findViewById(R.id.text1);
recview = findViewById(R.id.recview);
linearLayoutManager = new LinearLayoutManager(this);
recview.setLayoutManager(linearLayoutManager);
instanceforAPI = retrofitInstance.getRetrofit().create(apiInterface.class);
instanceforAPI.getdata().enqueue(new Callback<List<jsonData>>() {
#Override
public void onResponse(Call<List<jsonData>> call, Response<List<jsonData>> response) {
if(response.body().size()>0){
Toast.makeText(MainActivity.this,"yayy",Toast.LENGTH_LONG).show();
data.addAll(response.body());
ad = new adapter(data);
ad.notifyDataSetChanged();
recview.setAdapter(ad);
// for (int index=0;index<data.size();index++){
// txt.setText(txt.getText()+ " SRNo.: "+data.get(index).getTitle()+" \n" + data.size());
//
// }
}
else
{
Toast.makeText(MainActivity.this,"No yayy",Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<List<jsonData>> call, Throwable t) {
Toast.makeText(MainActivity.this,t.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
}
SingleRow design XML class (single.xml) is as follows:
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:rotationX="8">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/t1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
></TextView>
<TextView
android:id="#+id/t2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="title"
></TextView>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
Adapter class (adapter.java) for fetching data is as follows:
package com.example.apipractice;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class adapter extends RecyclerView.Adapter<adapter.myviewholder> {
List<jsonData> data;
public adapter(List<jsonData> data){
this.data = data;
}
#Override
public myviewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.single,parent,false );
return new myviewholder(v);
}
#Override
public void onBindViewHolder(#NonNull adapter.myviewholder holder, int position) {
holder.t1.setText((int) data.get(position).getId());
holder.t2.setText( data.get(position).getTitle());
}
#Override
public int getItemCount() {
return data.size();
}
public class myviewholder extends RecyclerView.ViewHolder
{
TextView t1,t2;
public myviewholder(#NonNull View itemView) {
super(itemView);
t1= itemView.findViewById(R.id.t1);
t2 = itemView.findViewById(R.id.t2);
}
}
}
The following class is for retrofit instance, retrofitInstance.java:
package com.example.apipractice;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class retrofitInstance {
private static Retrofit retrofit;
private static final String commonURL = "https://jsonplaceholder.typicode.com";
public static Retrofit getRetrofit() {
if(retrofit ==null) {
retrofit = new Retrofit.Builder().baseUrl(commonURL).addConverterFactory(GsonConverterFactory.create()).build();
}
return retrofit;
}
}
This interface class (apiInterfce.java) is for the API get call:
package com.example.apipractice;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;
public interface apiInterface {
#GET("/posts?type=json")
Call<List<jsonData>> getdata();
}
My model class, jsonData.java:
package com.example.apipractice;
public class jsonData {
private float userId;
private float id;
private String title;
private String body;
// Getter Methods
public float getUserId() {
return userId;
}
public float getId() {
return id;
}
public String getTitle() {
return title;
}
public String getBody() {
return body;
}
// Setter Methods
public void setUserId(float userId) {
this.userId = userId;
}
public void setId(float id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setBody(String body) {
this.body = body;
}
}
Don't pass int value in setText() method. Because it consider int value as a resource id.
Please do as follow:
#Override
public void onBindViewHolder(#NonNull adapter.myviewholder holder, int position) {
holder.t1.setText(data.get(position).getId() + "");
holder.t2.setText( data.get(position).getTitle());
}

RecylerView does not list items in order when added dynamicly after 3rd item added

I have a button that says ADD ITEM.
Below there is a RECYCLERVIEW.
When you click on ADD ITEM it adds an EDITVIEW to the recycler view. You type text in it, and then click on ADD ITEM again and it adds another EDITVIEW to the recyler view.
Everything is in the right order.
When you click on ADD ITEM for the 4th time, instead of adding at the 4th position, it adds at the 1st position and moves the previous 3 items down 1.
What could be causing this?
Main Activity
package com.app.bowling.animalsrecycler;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import java.util.ArrayList;
import static java.sql.Types.NULL;
public class MainActivity extends Activity implements RemoveClickListner{
private RecyclerView mRecyclerView;
private RecyclerAdapter mRecyclerAdapter;
private RecyclerView.LayoutManager mLayoutManager;
Button btnAddItem;
ArrayList<RecyclerData> myList = new ArrayList<>();
EditText etTitle;
String title = "";
ImageView crossImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerAdapter = new RecyclerAdapter(myList,this);
mRecyclerView.setLayoutManager(new GridLayoutManager(this,2));
mRecyclerView.setAdapter(mRecyclerAdapter);
etTitle = (EditText) findViewById(R.id.etTitle);
if (mRecyclerAdapter.getItemCount() == 0 || mRecyclerAdapter.getItemCount() == NULL){
Toast.makeText(getApplicationContext(),"ZERO ITEMS LISTED",Toast.LENGTH_SHORT).show();
}
btnAddItem = (Button) findViewById(R.id.btnAddItem);
btnAddItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
title = etTitle.getText().toString();
// if (title.matches("")) {
// Toast.makeText(v.getContext(), "You did not enter a Title", Toast.LENGTH_SHORT).show();
// return;
// }
RecyclerData mLog = new RecyclerData();
// mLog.setTitle(title);
myList.add(mLog);
mRecyclerAdapter.notifyData(myList);
etTitle.setText("");
if (mRecyclerAdapter.getItemCount() > 0) {
Toast.makeText(v.getContext(), mRecyclerAdapter.getItemCount() + " Items Displayed", Toast.LENGTH_SHORT).show();
return;
}
}
});
}
#Override
public void OnRemoveClick(int index) {
myList.remove(index);
mRecyclerAdapter.notifyData(myList);
}
}
RecyclerAdapter
package com.app.bowling.animalsrecycler;
import android.support.constraint.ConstraintLayout;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerItemViewHolder> {
private ArrayList<RecyclerData> myList;
int mLastPosition = 0;
private RemoveClickListner mListner;
public RecyclerAdapter(ArrayList<RecyclerData> myList,RemoveClickListner listner) {
this.myList = myList;
mListner=listner;
}
public RecyclerItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item, parent, false);
RecyclerItemViewHolder holder = new RecyclerItemViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(RecyclerItemViewHolder holder, final int position) {
Log.d("onBindViewHolder ", myList.size() + "");
mLastPosition = position;
holder.crossImage.setImageResource(R.drawable.ic_add_circle_black_24dp);
holder.etTitleTextView.setHint("Enter Player " + (position + 1));
holder.etTitleTextView.requestFocus();
}
#Override
public int getItemCount() {
return(null != myList?myList.size():0);
}
public void notifyData(ArrayList<RecyclerData> myList) {
Log.d("notifyData ", myList.size() + "");
this.myList = myList;
notifyDataSetChanged();
}
public class RecyclerItemViewHolder extends RecyclerView.ViewHolder {
private final TextView etTitleTextView;
private ConstraintLayout mainLayout;
public ImageView crossImage;
public RecyclerItemViewHolder(final View parent) {
super(parent);
etTitleTextView = parent.findViewById(R.id.txtTitle);
etTitleTextView.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
myList.get(getAdapterPosition()).setTitle(etTitleTextView.getText().toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
crossImage = (ImageView) parent.findViewById(R.id.crossImage);
mainLayout = (ConstraintLayout) parent.findViewById(R.id.mainLayout);
mainLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(itemView.getContext(), "Position:" + Integer.toString(getPosition()), Toast.LENGTH_SHORT).show();
}
});
crossImage.setOnClickListener(new AdapterView.OnClickListener() {
#Override
public void onClick(View view) {
mListner.OnRemoveClick(getAdapterPosition()
);
}
});
}
}
RecyclerData
package com.app.bowling.animalsrecycler;
import android.support.v7.widget.RecyclerView;
import android.widget.ImageView;
public class RecyclerData {
String title;
RecyclerView data;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public void setCrossImage(ImageView crossImage){
setCrossImage(crossImage);
}
}
RemoveClickLstner
package com.app.bowling.animalsrecycler;
public interface RemoveClickListner {
void OnRemoveClick(int index);
}
Activity_Main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:padding="16dp"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Title"
android:id="#+id/etTitle" />
<Button
android:id="#+id/btnAddItem"
android:text="Add Item"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#dbfffe" />
</LinearLayout>
RecyclerView_Item
<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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_margin="8dp"
android:id="#+id/cardview"
android:layout_height="112dp">
<android.support.constraint.ConstraintLayout
android:id="#+id/mainLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="#+id/txtTitle"
android:maxLines="1"
android:inputType="text"
android:maxLength="15"
android:layout_width="273dp"
android:layout_height="56dp"
android:layout_marginEnd="122dp"
android:layout_marginBottom="56dp"
android:padding="12dp"
android:textColor="#android:color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_conversion_absoluteHeight="0dp"
tools:layout_conversion_absoluteWidth="0dp"
tools:layout_conversion_wrapHeight="0"
tools:layout_conversion_wrapWidth="0" />
<ImageView
android:id="#+id/crossImage"
android:layout_width="136dp"
android:layout_height="112dp"
android:layout_marginStart="273dp"
android:background="#drawable/ic_add_circle_black_24dp"
android:paddingLeft="10dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_conversion_absoluteHeight="0dp"
tools:layout_conversion_absoluteWidth="0dp"
tools:layout_conversion_wrapHeight="0"
tools:layout_conversion_wrapWidth="0" />
</android.support.constraint.ConstraintLayout>
</LinearLayout>
Just try to replace your below snippet
myList.add(mLog);
mRecyclerAdapter.notifyData(myList);
etTitle.setText("");
Add this:
myList.add(mLog);
mRecyclerAdapter.addAll(myList);
mRecyclerAdapter.notifyDataSetChanged();
etTitle.setText("");
I would like to see your layout activity_main and recycler_view item because I have tried implementing your code with few twist and the code is working well please check the code below
https://github.com/muchbeer/StackOverflowRecyclerView
Please find the below Screen Shot
Kindy let me if this was your intended application

Expandable layout Expands upwards instead of downwards

When i try to put my Expandable layout to the bottom of my cardview using
android:layout_gravity="bottom" it goes to the bottom but expands upwards
After clicking the relative layout "button"
I am getting data from arraylist passing it to the recyclerview and cardview
i don't know if it's because of the Adapter animation settings or just fomr the xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_gravity="top"
android:id="#+id/cardview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginEnd="8dp"
android:layout_marginBottom="551dp"
android:animateLayoutChanges="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/holderimg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageView5"
android:layout_width="68dp"
android:layout_height="62dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
app:srcCompat="#drawable/s1960678" />
<TextView
android:id="#+id/nameArray"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:fontFamily="serif"
android:includeFontPadding="false"
android:text="TextView"
android:textSize="14sp"
android:textStyle="bold" />
<RelativeLayout
android:id="#+id/button"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentRight="true"
android:layout_gravity="right"
android:layout_marginTop="30dp"
android:layout_marginRight="10dp"
android:background="#drawable/ic_arrow_drop_down_black_24dp"
android:foregroundGravity="right"
android:gravity="right|center_horizontal"
android:orientation="vertical">
<View
android:id="#+id/view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
<com.github.aakira.expandablelayout.ExpandableLinearLayout
android:id="#+id/expandableLayout"
android:layout_width="match_parent"
android:layout_height="72dp"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:foregroundGravity="bottom"
android:gravity="top"
android:orientation="vertical"
app:ael_duration="400"
app:ael_expanded="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="#+id/button3"
android:layout_width="199dp"
android:layout_height="wrap_content"
android:text="Button"
tools:text="Download .PDF" />
<Button
android:id="#+id/button5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button"
tools:text="View PDF" />
</LinearLayout>
</com.github.aakira.expandablelayout.ExpandableLinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
and here's the activity it gets data from , it's xml has only recyclerview
package com.example.imc.PDF;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.example.imc.MainAdapter;
import com.example.imc.MySingleton;
import com.example.imc.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class Resultsdwldview extends AppCompatActivity {
public RequestQueue requestQueue;
TextView MedicalText,PhoneText,AddressText,EmailText,result,resultArray;
EditText id;
Button getidbtn;
List<ArrayList<String>> Tests = new ArrayList<>();
ArrayList<String> urlArray = new ArrayList<String>();
ArrayList<String> nameArray = new ArrayList<String>();
ArrayList<String> IdfromjsonArray = new ArrayList<String>();
ArrayList<String> Patient_ID_Array = new ArrayList<String>();
RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;
RecyclerView.Adapter mAdapter;
WebView webView;
String PDFurl;
String idvalue;
String url = "https://docs.google.com/viewer?url=http://www.adobe.com/devnet/acrobat/pdfs/pdf_open_parameters.pdf";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_resultsdwldview);
MedicalText = findViewById(R.id.MedicalText);
PhoneText = findViewById(R.id.PhoneText);
AddressText = findViewById(R.id.AddressText);
EmailText = findViewById(R.id.EmailText);
// webView = findViewById(R.id.webview); //WEBVIEW
// webView.requestFocus();
// webView.getSettings().setJavaScriptEnabled(true);
// webView.loadUrl(url);
mRecyclerView = findViewById(R.id.recyvlerView);
// id = findViewById(R.id.getid);
// getidbtn =(Button) findViewById(R.id.send);
mLayoutManager = new LinearLayoutManager(this);
jsonParse();
/*
getidbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//idvalue = id.getEditableText().toString();
jsonParse();
}
});*/
}
public void jsonParse() {
String URL="http://ashaaban-001-site1.btempurl.com/api/patients/"+4;
//String URL="http://ashaaban-001-site1.btempurl.com/api/patients/"+idvalue;
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, URL, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("Tests");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject arraydata = jsonArray.getJSONObject(i);
// Tests.add(jsonObject.getString(String.valueOf(i)));
String urlName = arraydata.getString("urlName");
String Name =arraydata.getString("Name");
String Idfromjson =arraydata.getString("Id");
String P_ID_Array =arraydata.getString("patients_Id");
urlArray.add(urlName);
nameArray.add(Name);
IdfromjsonArray.add(Idfromjson);
Patient_ID_Array.add(P_ID_Array);
Tests.add(urlArray);
Tests.add(nameArray);
Tests.add(IdfromjsonArray);
Tests.add(Patient_ID_Array);
// resultArray.append("urlName = " +urlName+" \n\n Name"+Name);
}
//resultArray.append(Tests+" , \n ");
// mRecyclerView.setHasFixedSize(true);
} catch (JSONException e) {
e.printStackTrace();
}
try {
Integer P_MedicalNumber = response.getInt("MedicalNumber");
Integer P_id = response.getInt("Id");
String P_Username = response.getString("UserName");
Integer P_PhoneNumber = response.getInt("phoneNumber");
String P_Address = response.getString("Address");
String P_Email = response.getString("Email");
//result.append("Medical Number : "+P_MedicalNumber+" \n id :"+P_id+"UserName"+P_Username);
} catch (JSONException e) {
e.printStackTrace();
}
mAdapter = new MainAdapter(Tests,nameArray);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setAdapter(mAdapter);
mAdapter.notifyItemRangeInserted(0, Tests.size());
// webView.loadUrl(PDFurl);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),"error",Toast.LENGTH_SHORT).show();
}
});
// requestQueue.add(request);
MySingleton.getInstance(Resultsdwldview.this).addToReqeustQueue(jsonObjectRequest);
}
}
Adapter
package com.example.imc;
import android.animation.ObjectAnimator;
import android.content.ClipData;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.github.aakira.expandablelayout.ExpandableLayout;
import com.github.aakira.expandablelayout.ExpandableLayoutListenerAdapter;
import com.github.aakira.expandablelayout.ExpandableLinearLayout;
import com.github.aakira.expandablelayout.Utils;
import java.util.ArrayList;
import java.util.List;
public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {
List<ArrayList<String>> Tests;
ArrayList<String> urlArray;
ArrayList<String> nameArray;
ArrayList<String> IdfromjsonArray ;
ArrayList<String> Patient_ID_Array;
SparseBooleanArray expandState =new SparseBooleanArray();
public MainAdapter(List<ArrayList<String>> tests, ArrayList<String> urlArray, ArrayList<String> nameArray,
ArrayList<String> idfromjsonArray, ArrayList<String> patient_ID_Array) {
Tests = tests;
this.urlArray = urlArray;
this.nameArray = nameArray;
IdfromjsonArray = idfromjsonArray;
Patient_ID_Array = patient_ID_Array;
}
public MainAdapter(List<ArrayList<String>> tests, ArrayList<String> nameArray) {
Tests = tests;
this.nameArray = nameArray;
}
#NonNull
#Override
//Initialize the viewholder
public MainAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row,viewGroup,false);
return new ViewHolder(view);
}
/***************////////////////onBind Holds values to pass it to the viewholder///////////////////*******************
/***************////////////////
// This method is called for each ViewHolder to
// bind it to the adapter
// . This is where we will// pass our data to our ViewHolder///////////////////*******************
#Override
public void onBindViewHolder(#NonNull final MainAdapter.ViewHolder holder, final int i) {
// holder.URLName.setText( urlArray.get(i));
holder.mFullname.setText( nameArray.get(i));
holder.expandableLayout.setInRecyclerView(true);
holder.expandableLayout.setExpanded(expandState.get(i));
holder.expandableLayout.setListener(new ExpandableLayoutListenerAdapter() {
#Override
public void onPreOpen() {
changeRotate(holder.button,180f,0f).start();
expandState.put(i,true);
}
#Override
public void onPreClose() {
changeRotate(holder.button,0f,180f).start();
expandState.put(i,false);
}
});
holder.button.setRotation(expandState.get(i)?0f:180f);
holder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Expandable child item
holder.expandableLayout.toggle();
}
});
}
private ObjectAnimator changeRotate(RelativeLayout button, float to, float from) {
ObjectAnimator animator = ObjectAnimator.ofFloat(button,"rotation",from,to);
animator.setDuration(200);
animator.setInterpolator(Utils.createInterpolator(Utils.LINEAR_INTERPOLATOR));
return animator;
}
#Override
public int getItemCount() {
return nameArray.size();
}
/***************////////////////VIEWHOLDER///////////////////*******************
public class ViewHolder extends RecyclerView.ViewHolder {
// public TextView URLName;
public TextView mFullname;
public RelativeLayout button;
public ExpandableLinearLayout expandableLayout;
public ViewHolder(#NonNull View itemView) {
super(itemView);
mFullname=itemView.findViewById(R.id.nameArray);
//URLName=itemView.findViewById(R.id.URLName);
button=itemView.findViewById(R.id.button);
expandableLayout=itemView.findViewById(R.id.expandableLayout);
}
}
}

Custom Adapter not working for RecyclerView in a Fragment

I am working on an Android Project to display Github repo details.
I am trying to first select org name for a particular company, like Amazon has orgs on Github like AWS, AMZN, AWSLABS etc.
For this I first create a List of clickable buttons via RecyclerView(which works).
Then when user clicks on a particular org_name, the App does a HTTP request to Github to fetch relevant info and display inside a fragment which uses another RecyclerView(not working RecyclerViewRepoAdapter.java).
This part does not work as onCreateViewHolder or onBindViewHolder is not called (getItemCount is called and returns correct length)
Tried some of the suggestions mentioned like in this link! but it didn't work.
Any help is appreciated!
OrganizationInfo.java // Driver program
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class OrganizationInfo extends AppCompatActivity {
private String companyName;
private String companyAddress;
private List<String> orgNames;
private TextView companyNameTV;
private TextView companyAddressTV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_organization_info);
getCompanyData();
companyNameTV = findViewById(R.id.companyNameTv);
companyAddressTV = findViewById(R.id.companyAddressTv);
companyNameTV.setText(companyName);
companyAddressTV.setText(companyAddress);
initRecyclerView();
}
private void getCompanyData() {
companyName = "amazon";
companyAddress = "207 Boren Ave N, Seattle, WA 98109";
orgNames = new ArrayList<>();
orgNames.add("amzn");
orgNames.add("aws");
orgNames.add("awslabs");
}
private void initRecyclerView(){
// Log.d(TAG, "initRecyclerView: init recyclerview");
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView recyclerView = findViewById(R.id.orgListRecyclerView);
recyclerView.setLayoutManager(layoutManager);
RecyclerViewOrgAdapter adapter = new RecyclerViewOrgAdapter(this, orgNames);
recyclerView.setAdapter(adapter);
}
}
GithubFragment.java
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A simple {#link Fragment} subclass.
*/
public class GithubFragment extends Fragment {
private List<Repository> repositories = new ArrayList<>();
RecyclerView recyclerView;
RecyclerViewRepoAdapter listAdapter;
public GithubFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
assert getArguments() != null;
View v = inflater.inflate(R.layout.fragment_github, container, false);
recyclerView = v.findViewById(R.id.repo_recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
listAdapter = new RecyclerViewRepoAdapter(getContext(), repositories); // List of Github repos to be display
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(listAdapter); // Called from here after response from cloud funtion
return v;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
if (getArguments() != null) {
String orgName = getArguments().getString("org_name");
GraphQLAsyncTask graphQLAsyncTask = new GraphQLAsyncTask();
graphQLAsyncTask.execute(orgName, "");
}
}
private class GraphQLAsyncTask extends AsyncTask<String, String, String> {
private String response;
private Reader in;
#Override
protected String doInBackground(String... body) {
Map<String, String> params = new HashMap<>();
params.put("company", body[0]);
params.put("language", body[1]);
StringBuilder postData = new StringBuilder();
try{
for (Map.Entry param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(param.getKey().toString(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
String url = "https://****************/getOrgReposGraphQL";
URL urlObj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept-Charset", "UTF-8");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.getOutputStream().write(postDataBytes);
conn.connect();
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0; )
sb.append((char) c);
response = sb.toString();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
#Override
protected void onPostExecute(String response) {
ParseResponse parseResponse = new ParseResponse(response);
repositories.addAll(parseResponse.getRepositories());
listAdapter.notifyDataSetChanged();
}
}
}
RecyclerViewRepoAdapter.java // Problematic Adapter
package edu.neu.madcourse.goexplore;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class RecyclerViewRepoAdapter extends RecyclerView.Adapter<RecyclerViewRepoAdapter.ListViewHolder> {
private List<Repository> mRepositories;
private Context mContext;
private int mCounter = 1;
public RecyclerViewRepoAdapter(Context context, List<Repository> repos) {
mRepositories = repos;
mContext = context;
}
#NonNull
#Override
public ListViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_repo, parent, false);
return new ListViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ListViewHolder holder, int position) {
Repository repo = mRepositories.get(position);
holder.repoTV.setText(repo.getNameWithOwner());
holder.repoLangugeTV.setText(repo.getPrimaryLanguage());
holder.repoStarsTV.setText(repo.getStargazers());
holder.repoCounter.setText(String.valueOf(mCounter++) + ".");
}
#Override
public int getItemCount() {
return mRepositories.size();
}
public class ListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView repoTV;
TextView repoLangugeTV;
TextView repoStarsTV;
TextView repoCounter;
public ListViewHolder(View itemView) {
super(itemView);
repoTV = itemView.findViewById(R.id.repo_name_row);
repoLangugeTV = itemView.findViewById(R.id.repo_language_tv);
repoStarsTV = itemView.findViewById(R.id.repo_stars_tv);
repoCounter = itemView.findViewById(R.id.repo_list_number);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
}
}
}
RecyclerViewOrgAdapter.java
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class RecyclerViewOrgAdapter extends RecyclerView.Adapter<RecyclerViewOrgAdapter.ViewHolder> {
private static final String TAG = "RecyclerViewOrgAdapter";
private List<String> orgs;
private Context context;
public RecyclerViewOrgAdapter(Context context, List<String> orgs) {
this.orgs = orgs;
this.context = context;
}
#NonNull
#Override
public RecyclerViewOrgAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.organization_id_relative_layout, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final RecyclerViewOrgAdapter.ViewHolder holder, final int position) {
holder.orgIdBtn.setText(orgs.get(position));
holder.orgIdBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AppCompatActivity activity = (AppCompatActivity) v.getContext();
Fragment githubFragment = new GithubFragment();
Bundle bundle = new Bundle();
bundle.putString("org_name", orgs.get(position));
githubFragment.setArguments(bundle);
activity.getSupportFragmentManager().beginTransaction().replace(R.id.github_fragment, githubFragment).addToBackStack(null).commit();
}
});
}
#Override
public int getItemCount() {
return orgs.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
Button orgIdBtn;
public ViewHolder(View itemView) {
super(itemView);
orgIdBtn = itemView.findViewById(R.id.orgIdBtn);
}
}
}
list_item_repo.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/repo_list_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="1."
android:textSize="24sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/repo_name_row"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:text="Repo Name"
android:textSize="24sp"
app:layout_constraintStart_toEndOf="#+id/repo_list_number"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageView2"
android:layout_width="42dp"
android:layout_height="33dp"
android:layout_marginTop="12dp"
app:layout_constraintStart_toStartOf="#+id/repo_name_row"
app:layout_constraintTop_toBottomOf="#+id/repo_name_row"
app:srcCompat="#mipmap/star_dark_round" />
<TextView
android:id="#+id/repo_stars_tv"
android:layout_width="42dp"
android:layout_height="33dp"
android:layout_marginStart="16dp"
android:text="1441"
app:layout_constraintBottom_toBottomOf="#+id/imageView2"
app:layout_constraintStart_toEndOf="#+id/imageView2"
app:layout_constraintTop_toTopOf="#+id/imageView2" />
<TextView
android:id="#+id/repo_language_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:text="Ruby"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="#+id/repo_stars_tv"
app:layout_constraintStart_toEndOf="#+id/repo_stars_tv"
app:layout_constraintTop_toTopOf="#+id/repo_stars_tv" />
</LinearLayout>
</LinearLayout>
fragment_github.xml
<?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="match_parent"
android:orientation="vertical"
tools:context=".GithubFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/repo_recycler_view"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent" />
</LinearLayout>
You are attaching adapter after getting a response from the API
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
listAdapter = new RecyclerViewRepoAdapter(getContext(), repositories); // List of Github repos to be display
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(listAdapter); // Called from here after response from cloud funtion
Move this code in onCreateView
assert getArguments() != null;
View v = inflater.inflate(R.layout.fragment_github, container, false);
recyclerView = v.findViewById(R.id.repo_recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
listAdapter = new RecyclerViewRepoAdapter(getContext(), repositories); // List of Github repos to be display
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(listAdapter); // Called from here after response from cloud funtion
return v;
And after getting a response from Api in AsyncTask onPostExecute() Method add data into list and notify adapter
ParseResponse parseResponse = new ParseResponse(response);
repositories = parseResponse.getRepositories();
listAdapter.notifyDataSetChanged();

Categories

Resources