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());
}
Related
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();
}
}
I am unable to display the image (only) in RecyclerView stored in Firebase Storage, while I'm displaying the other text data in the recyclerView.
I browse through a lot of questions but i didn't find the answer for me .
hint: all roles for Realtime Database , Firebase Storage is set either to [true or test mode]
hint : below is the link for out put image :
https://i.stack.imgur.com/dagbA.jpg
data model
import com.google.firebase.database.Exclude;
public class House {
#Exclude
private String key;
//owner name
private String name ;
//location
private String Location;
//image
private String imageUrl;
/*all start with [RealState] (realTimeDatabase/storage)*/
/*
* [RealStateData] - database
* [RealStatePictures] - storage
* */
public House() {
//required
}
public House(String name, String location, String imageUrl) {
if (name.trim().equals("") || name.isEmpty()){
name = "realState company";
}
this.name = name;
Location = location;
this.imageUrl = imageUrl;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return Location;
}
public void setLocation(String location) {
Location = location;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
#Exclude
public String getKey() {
return key;
}
#Exclude
public void setKey(String key) {
this.key = key;
}
}
Adapter
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.squareup.picasso.Picasso;
import com.techmarinar.royalhomes.data.House;
import java.util.List;
public class HouseAdapter extends RecyclerView.Adapter<HouseAdapter.HouseHolder> {
private static final String TAG = "HouseAdapter";
private Context mContext;
private List<House> houseList;
public HouseAdapter(Context mContext, List<House> houseList) {
this.mContext = mContext;
this.houseList = houseList;
}
public void setUploads(List<House> uploads) {
this.houseList = uploads;
this.notifyDataSetChanged();
}
#NonNull
#Override
public HouseHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v= LayoutInflater.from(mContext)
.inflate(R.layout.list_item,parent,false);
return new HouseHolder(v);
}
#Override
public void onBindViewHolder(#NonNull HouseHolder holder, int position) {
//house object
House house = houseList.get(position);
holder.name.setText(house.getName());
holder.location.setText(house.getLocation());
// holder.image.setImageURI(Uri .parse(house.getImageUrl());
String imageUrl = house.getImageUrl();
Glide.with(mContext)
.load(imageUrl)
.placeholder(R.drawable.ic_baseline_add_business_24)
.centerCrop()
.into(holder.image);
}
#Override
public int getItemCount() {
return houseList.size();
}
#Override
public long getItemId(int position) {
return position;
}
public class HouseHolder extends RecyclerView.ViewHolder {
private ImageView image;
private TextView name;
private TextView location ;
public HouseHolder(#NonNull View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.xHouseImage);
name = (TextView) itemView.findViewById(R.id.xHouseName);
location = (TextView) itemView.findViewById(R.id.xHouseLocation);
}
}
}
MainActicity -- recyclerclass
package com.techmarinar.royalhomes;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.techmarinar.royalhomes.data.House;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements MenuItem.OnMenuItemClickListener {
private static final String TAG = "MainActivity";
//widget
private RecyclerView mRecycler;
private ProgressBar mProgress;
//firebase Element
private StorageReference storageReference;
private DatabaseReference databaseReference;
//Adapters var
private List<House> houseList;
private HouseAdapter mAdapter;
private ValueEventListener getFirebaseData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set Widget
setupUIWidget();
//init firebase
initiateFireBaseElement();
//set recyclerView
setupRecyclerView();
//get data from fire(storage/fireDataBase);
getHousesDataFromFireBase();
//setup Item Touch Helper
setupItemTouchHelper(mRecycler , mAdapter);
}
private void setupUIWidget() {
setTitle("home");
//widget
mProgress = (ProgressBar) findViewById(R.id.progress_circular);
mRecycler = (RecyclerView) findViewById(R.id.recycler);
FloatingActionButton mActionButton = (FloatingActionButton) findViewById(R.id.floatingBtn);
//ActionButton
mActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Toast.makeText(MainActivity.this, "wow", Toast.LENGTH_SHORT).show();
startActivity(new Intent(MainActivity.this , EditHouse.class));
}
});
}
private void initiateFireBaseElement() {
//fireBase reference
databaseReference = FirebaseDatabase.getInstance().getReference("RealStateData");
storageReference= FirebaseStorage.getInstance().getReference("RealStatePictures") ;
}
private void setupRecyclerView() {
Log.d(TAG, "setupRecyclerView: ");
houseList = new ArrayList<>();
mRecycler.setLayoutManager(new LinearLayoutManager(this));
mRecycler.setHasFixedSize(true);
//mRecycler.setHasStableIds(true);
//init adapter
mAdapter = new HouseAdapter(MainActivity.this,houseList);
//set adapter to the recyclerView
mRecycler.setAdapter(mAdapter);
}
private void getHousesDataFromFireBase() {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
houseList.clear();
for (DataSnapshot data : snapshot.getChildren()) {
//init house object
House houseValues = data.getValue(House.class);
// houseValues.setKey(data.getKey());
//fill the list
houseList.add(houseValues);
}
//notify the adapter
mAdapter.setUploads(houseList);
//mAdapter.notifyDataSetChanged();
//hide the progressBar
mProgress.setVisibility(View.INVISIBLE);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.d(TAG, "onCancelled: " + error.getMessage());
Toast.makeText(MainActivity.this, "" + error.getMessage(), Toast.LENGTH_SHORT).show();
//hide progressbar
mProgress.setVisibility(View.INVISIBLE);
}
});
}
private void setupItemTouchHelper(RecyclerView mRecycler, HouseAdapter mAdapter) {
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
}).attachToRecyclerView(mRecycler);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//menu
MenuItem addNewHouse , deleteHouse , updateHouse;
addNewHouse= menu.add(0,1,1,"add house");
addNewHouse.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
addNewHouse.setIcon(R.drawable.ic_baseline_supervised_user_circle_24);
updateHouse= menu.add(0,2,2,"update house");
deleteHouse= menu.add(0,3,3,"delete house");
addNewHouse.setOnMenuItemClickListener(this);
updateHouse.setOnMenuItemClickListener(this);
deleteHouse.setOnMenuItemClickListener(this);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case 1:
Toast.makeText(this, "new house", Toast.LENGTH_SHORT).show();
return true;
case 2:
Toast.makeText(this, "update house data", Toast.LENGTH_SHORT).show();
return true;
case 3:
Toast.makeText(this, "delete house data", Toast.LENGTH_SHORT).show();
return true;
default:return false;
}
}
}
here is xml files
List item:
<?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"
android:layout_margin="2dp"
app:cardBackgroundColor="#color/purple_200"
app:cardElevation="12dp"
app:cardCornerRadius="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="8dp">
<!--this view is only for beautiful looks -->
<View
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#color/purple_200"/>
<!--this view is only for beautiful looks -->
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/white"/>
<ImageView
android:id="#+id/xHouseImage"
android:layout_width="match_parent"
android:layout_height="220dp"
android:adjustViewBounds="true" />
<!--this view is only for beautiful looks -->
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/white"/>
<TextView
android:id="#+id/xHouseLocation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="house Location"
android:layout_margin="4dp"
android:layout_marginStart="6dp"
android:fontFamily="sans-serif-light"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
android:textStyle="bold"
android:textColor="#color/black"
android:textSize="33sp"/>
<TextView
android:id="#+id/xHouseName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="house owner name"
android:layout_margin="4dp"
android:layout_marginStart="8dp"
android:fontFamily="sans-serif-light"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
android:textColor="#color/black"
android:textSize="16sp"
android:gravity="top|center_vertical" />
</LinearLayout>
</androidx.cardview.widget.CardView>
recycler
<?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=".MainActivity"
android:layout_margin="8dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
app:layout_goneMarginBottom="8dp">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="4dp"
android:layout_marginBottom="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.029" />
<ProgressBar
android:id="#+id/progress_circular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.446"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.406" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_baseline_home_work_24"
android:backgroundTint="#color/white"
android:foregroundGravity="bottom|right"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.905"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.945" />
</androidx.constraintlayout.widget.ConstraintLayout>
Try this applyDefaultRequestOptions Method for Center crop of the image
Glide.with(mContext)
.applyDefaultRequestOptions(RequestOptions().centerCrop())
.load(imageUrl)
.placeholder(R.drawable.ic_baseline_add_business_24)
.into(target!!)
the problem was in Manifest.xml security issuess.
solution :
adding
android:usesCleartextTraffic="true"
to the application section
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>
I don't know in which part i made mistake. In UploadItemAdapter.class,uploadingDetails.getTitle() and uploadingDetails.getDiscription() both gives me null in my log cat. In android listView screen textView of item is also remains blank Screenshot .My Computer Screen.
My code is mentioned below.
UploadItemAdapter.java
package com.example.shiva.gconnection.extendedVersion;
import android.content.Context;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.example.shiva.gconnection.R;
import com.example.shiva.gconnection.UploadingDetails;
import java.util.List;
/**
* Created by shiva on 3/3/18.
*/
public class UploadItemAdapter extends ArrayAdapter<UploadingDetails>{
public UploadItemAdapter( Context context, int resource, List<UploadingDetails> objects) {
super(context, resource, objects);
}
#Override
public View getView(int position ,View convertView,ViewGroup parent) {
if (convertView == null) {
convertView = ((FragmentActivity) getContext()).getLayoutInflater().inflate(R.layout.uploaded_material_child, parent, false);
}
TextView titalTV = (TextView) convertView.findViewById(R.id.title_item_upload_material);
TextView discriptionTV= (TextView) convertView.findViewById(R.id.discription_item_upload_material);
UploadingDetails uploadingDetails = getItem(position);
titalTV.setText(uploadingDetails.getTitle());
discriptionTV.setText(uploadingDetails.getDiscription());
Log.v("abcd",uploadingDetails.getTitle() +" "+uploadingDetails.getDiscription());
return convertView;
}
}
uploaded_material.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:layout_margin="10dp"
android:orientation="vertical">
<ListView
android:id="#+id/lv_upload_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transcriptMode="alwaysScroll"
tools:listitem="#layout/uploaded_material_child" />
</LinearLayout>
Uploaded_material_child.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Title"
android:id="#+id/title_item_upload_material"
android:textSize="20dp"
android:textColor="#android:color/black"
android:layout_margin="5dp"/>
<TextView
android:layout_margin="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Discription"
android:textColor="#android:color/black"
android:id="#+id/discription_item_upload_material"
android:textSize="16dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="UploadedBy"
android:id="#+id/uploaded_by"
android:textSize="16dp"
android:textColor="#android:color/black"
android:layout_margin="5dp"/>
</LinearLayout>
FragmentLastView.java
package com.example.shiva.gconnection.extendedVersion;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.example.shiva.gconnection.R;
import com.example.shiva.gconnection.UploadingDetails;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import java.util.ArrayList;
public class FragmentLastView extends Fragment {
private FirebaseDatabase mdatabase;
private DatabaseReference mdbRef;
private ListView mItemLV;
private ChildEventListener childEventListener;
private ArrayAdapter mUploadItemAdapter;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.uploaded_material,container,false);
mdatabase = FirebaseDatabase.getInstance();
mdbRef = mdatabase.getReference("College");
return view;
}
#Override
public void onViewCreated(View view,Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final String subjectName = getArguments().getString("SubjectName");
final String branchname = getArguments().getString("BranchName");
final String class1Name = getArguments().getString("Class1Name");
final String className = getArguments().getString("ClassName");
final ArrayList<UploadingDetails> uploadingDetails = new ArrayList<>();
mItemLV= (ListView)view.findViewById(R.id.lv_upload_item);
mUploadItemAdapter = new UploadItemAdapter(view.getContext(),R.layout.uploaded_material_child,uploadingDetails);
mItemLV.setAdapter(mUploadItemAdapter);
childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
UploadingDetails updetails = dataSnapshot.getValue(UploadingDetails.class);
uploadingDetails.add(updetails);
mUploadItemAdapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
mdbRef.child(branchname).child(subjectName).child(className).child(class1Name).addChildEventListener(childEventListener);
}
}
UploadingDetails.java
package com.example.shiva.gconnection;
public class UploadingDetails {
private String mTitle;
private String mDiscription;
private String mArrayUri;
public UploadingDetails(){
}
public UploadingDetails(String title, String discription,String arrayUri){
this.mTitle= title;
this.mDiscription=discription;
this.mArrayUri=arrayUri;
}
public String getTitle(){
return this.mTitle;
}
public String getDiscription(){
return this.mDiscription;
}
public String getArrayUri(){return this.mArrayUri;}
}
The name of the fields in your model class must much to the name of the data on witch your want retrieve in firebase data reference node
I don't understand how it worked but when i changed following code problem was solved
UploadindDetils.java
package com.example.shiva.gconnection;
public class UploadingDetails {
private String mTitle;
private String mDiscription;
private String mArrayUri;
public UploadingDetails() {
}
public UploadingDetails(String title, String discription, String arrayUri) {
this.mTitle = title;
this.mDiscription = discription;
this.mArrayUri = arrayUri;
}
public String getTitle() {
return this.mTitle;
}
public void setTitle(String title) {
this. mTitle = title;
}
public void setDiscription(String discription) {
this.mDiscription = discription;
}
public void setArrayUri(String arrayUri) {
this.mArrayUri = arrayUri;
}
public String getDiscription() {
return this.mDiscription;
}
public String getArrayUri() {
return this.mArrayUri;
}
}
I have 2 recycler views, let's call then recycler1 and recycler2 (purple background). The squares with yellow background are elements of recycler2 which has an instance inside of each element of recycler1. What I'm trying to achieve is that it should scroll elements of recycler2 on purple area fling and recycler1 outside it. I made it with horizontal scroll (which is very easy) but can't do it vertically. I tried to set and reset nested scrolling and behaviour and whatever but can't make it work.
Below the code (a lot of it):
InnerItem Layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:layout_height="50dp"
android:layout_width="60dp"
android:background="#38f"
android:padding="4dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:background="#ffff00"
android:id="#+id/tag_text_view"
android:text="Some Content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
Nested recycler item
<?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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#cfcfcf"
>
<TextView
android:id="#+id/first_name_textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:textSize="20sp"
android:text="New Text"
android:background="#1ad"
/>
<TextView
android:id="#+id/last_name_textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="New Text"
android:gravity="center"
android:layout_margin="10dp"
android:textSize="16sp"
android:padding="10dp"
android:background="#d65"
/>
<android.support.v7.widget.RecyclerView
android:id="#+id/nested_recycler"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#659"
>
</android.support.v7.widget.RecyclerView>
</LinearLayout>
Activity
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
InnerItem
package com.yrs.androidltx.features.adapterviews.nestedrecycler;
public class InnerItem {
String tag;
public InnerItem(String tag) {
this.tag = tag;
}
}
InnerItem Adapter
package com.yrs.androidltx.features.adapterviews.nestedrecycler;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.yrs.androidltx.R;
import java.util.List;
public class InnerItemAdapter extends RecyclerView.Adapter<InnerItemViewHolder> {
List<InnerItem> innerItemList;
public InnerItemAdapter(List<InnerItem> innerItemList) {
this.innerItemList = innerItemList;
}
#Override
public InnerItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater
.from(parent.getContext())
.inflate(R.layout.inner_item, parent, false);
InnerItemViewHolder viewHolder = new InnerItemViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(InnerItemViewHolder holder, int position){
holder.tagTextVIew.setText(innerItemList.get(position).tag);
}
#Override
public int getItemCount() {
return innerItemList.size();
}
}
InnerItem ViewHolder
package com.yrs.androidltx.features.adapterviews.nestedrecycler;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import com.yrs.androidltx.R;
public class InnerItemViewHolder extends RecyclerView.ViewHolder {
TextView tagTextVIew;
public InnerItemViewHolder(View itemView) {
super(itemView);
tagTextVIew = (TextView) itemView.findViewById(R.id.tag_text_view);
}
}
Person
package com.yrs.androidltx.features.adapterviews.nestedrecycler;
public class Person {
private String firstName;
private String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Person ViewHolder
package com.yrs.androidltx.features.adapterviews.nestedrecycler;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import com.yrs.androidltx.R;
public class PersonViewHolder extends RecyclerView.ViewHolder {
//Keep package visibility
TextView firstNameTextView;
TextView lastNameTextView;
RecyclerView nestedRecyclerView;
public PersonViewHolder(View itemView) {
super(itemView);
firstNameTextView = (TextView) itemView.findViewById(R.id.first_name_textView);
lastNameTextView = (TextView) itemView.findViewById(R.id.last_name_textView);
nestedRecyclerView = (RecyclerView) itemView.findViewById(R.id.nested_recycler);
}
}
Person Adapter
package com.yrs.androidltx.features.adapterviews.nestedrecycler;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.yrs.androidltx.R;
import java.util.ArrayList;
import java.util.List;
public class PersonAdapter extends RecyclerView.Adapter<PersonViewHolder> {
List<Person> personList;
public PersonAdapter(List<Person> personList) {
this.personList = personList;
}
#Override
public PersonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater
.from(parent.getContext())
.inflate(R.layout.nested_recycler_item, parent, false);
PersonViewHolder personViewHolder = new PersonViewHolder(view);
return personViewHolder;
}
#Override
public void onBindViewHolder(PersonViewHolder holder, int position) {
holder.firstNameTextView.setText(personList.get(position).getFirstName());
holder.lastNameTextView.setText(personList.get(position).getLastName());
holder.nestedRecyclerView.setLayoutManager(new GridLayoutManager(holder.nestedRecyclerView.getContext(), 3, GridLayoutManager.VERTICAL, false ));
holder.nestedRecyclerView.setAdapter(new InnerItemAdapter(initTagList()));
}
#Override
public int getItemCount() {
return personList.size();
}
private List<InnerItem> initTagList() {
List<InnerItem> tagList = new ArrayList<>();
tagList.add(new InnerItem("android"));
tagList.add(new InnerItem("iOS"));
tagList.add(new InnerItem("windows"));
tagList.add(new InnerItem("linux"));
tagList.add(new InnerItem("NetBSD"));
tagList.add(new InnerItem("NetWare"));
//repeat few times...
return tagList;
}
}
Main activity
package com.yrs.androidltx.features.adapterviews.nestedrecycler;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import com.yrs.androidltx.R;
import com.yrs.androidltx.activities.base.BaseActivity;
import java.util.ArrayList;
import java.util.List;
public class WithNestedRecyclerActivity extends BaseActivity {
private RecyclerView recyclerView;
private PersonAdapter personAdapter;
private RecyclerView.LayoutManager layoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_with_recycler);
recyclerView = (RecyclerView) findViewById(R.id.recycler);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
personAdapter = new PersonAdapter(initDataSet());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(personAdapter);
}
private List<Person> initDataSet() {
List<Person> personList = new ArrayList<>();
personList.add(new Person("Ned","Flanders"));
personList.add(new Person("Homer","Simpson"));
personList.add(new Person("Bart","Simpson"));
personList.add(new Person("Mr","Burns"));
//... repeat few times
return personList;
}
}