Embedding a RecyclerView within a custom view - java

I am trying to embed a RecyclerView within the body of a custom view (a RefreshableList).
This is my project's structure: it contains 2 modules, app & rlist.
the rlist module holds the custom view (RefreshableList) in which I want to embed a RecyclerView.
RefreshableList.java (The custom view)
public class RefreshableList extends RelativeLayout {
private RecyclerView mRecyclerView;
private Context mContext;
private MyAdapter mAdapter;
public RefreshableList(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
Log.i("ADAPTER", "RefreshableList is initializing views...");
setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
LayoutInflater inflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.refreshable_list, null);
findViewsById(view);
setupRecyclerView();
}
private void findViewsById(View view) {
mRecyclerView = (RecyclerView) view.findViewById(R.id.dataRecyclerView);
Log.i("ADAPTER", "RecyclerView has been initialized.");
}
private void setupRecyclerView() {
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
Log.i("ADAPTER", "RecyclerView has been setup.");
}
public void setAdapter(MyAdapter adapter) {
mAdapter = adapter;
mRecyclerView.setAdapter(mAdapter);
Log.i("ADAPTER", "Adapter has been set." + mAdapter.getItemCount());
}
}
MyAdapter.java (The RecyclerView's adapter)
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
protected Context mContext;
protected List<String> mItems;
public MyAdapter(Context context, List<String> items) {
mContext = context;
mItems = new ArrayList<>(items);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_row, parent, false);
Log.i("ADAPTER", "Creating row...");
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.label.setText(mItems.get(position));
}
#Override
public int getItemCount() {
return mItems.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView label;
public ViewHolder(View itemView) {
super(itemView);
label = (TextView) itemView.findViewById(R.id.label);
}
}
}
item_row.xml: (the XML layout of the RecyclerView's elements)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="60dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="New Text"
android:id="#+id/label"
android:gravity="left|center_vertical"
android:padding="8dp"
android:background="#ff0000"/>
</LinearLayout>
refreshable_list.xml: (The XML layout of the RefreshableList custom view)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/dataRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
All this code belongs to the rlist module. In order to test it out, I added a MainActivity to the app module where I embed a RefreshableList:
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Bind(R.id.list)
RefreshableList mRefreshableList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mRefreshableList.setAdapter(new MyAdapter(
this, Arrays.asList("Java", "Android", "Python", "Kivy")));
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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"
tools:context="com.zouag.refreshablelist.MainActivity"
android:background="#00ff00">
<com.zouag.rlist.RefreshableList
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffff00"/>
</RelativeLayout>
After running the application, I can't see any of the RecyclerView's elements: (even though the RecyclerView is clearly visible, marked with yellow)
What am I missing here ?

Not your recyclerview is visible, your relativelayout is.
You don't attach the inflated layout to your viewgroup.
The call :
View view = inflater.inflate(R.layout.refreshable_list, null);
just inflates the layout but dosen't attach it to a view.
If u wanna stick with this you need to attach the view after inflating by:
this.addView(view)
Or just call:
View view = inflater.inflate(R.layout.refreshable_list, this,true);
which attaches the inflated layout to the root view.

Related

Android Recycler returns zero output despite reaching onBindViewHolder() for each row

I've put a RecyclerView in the 'Tutorial' activity in my application, to list tutorial versions, which come from the Room database my app has. It is hosted within a fragment, but that's of little consequence since I had the same problem before putting it in there. The RecyclerView adapter reaches onBindViewHolder() without any issues and I get logs from the Log.w I used for debugging there with correct data. The problem seems to be that Layout does not get inflated at all, and the buttons that each row is supposed to output never appear.
THE ADAPTER
public class VersionListAdapter extends RecyclerView.Adapter<VersionListAdapter.VersionViewHolder> {
private List<Version> mVersionList;
private final LayoutInflater mInflater;
private final OnViewClickListener mListener;
public VersionListAdapter(Context context)
{
this.mInflater = LayoutInflater.from(context);
this.mVersionList = null;
this.mListener = (OnViewClickListener) context;
}
#NonNull
#Override
public VersionViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int viewType) {
View row = mInflater.inflate(R.layout.row_versions_rv, viewGroup, false);
return new VersionViewHolder(row, mListener);
}
#Override
public void onBindViewHolder(#NonNull VersionViewHolder versionHolder, int rowNumber) {
versionHolder.thisVersion = mVersionList.get(rowNumber);
versionHolder.versionButton.setText((mVersionList.get(rowNumber).getText()));
Log.w("THIS IS A TAG", mVersionList.get(rowNumber).getText()); //correct output
}
#Override
public int getItemCount() {
if(mVersionList!=null) return mVersionList.size();
else return 0;
}
public void setElementList(List<Version> versions){
this.mVersionList = versions;
notifyDataSetChanged();
}
public static class VersionViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener
{
OnViewClickListener listenerForThisRow;
Version thisVersion;
Button versionButton;
public VersionViewHolder(
#NonNull View viewForThisRow, OnViewClickListener listenerFromActivity)
{
super(viewForThisRow);
this.listenerForThisRow = listenerFromActivity;
versionButton = viewForThisRow.findViewById(R.id.version_button);
viewForThisRow.setOnClickListener(this);
}
#Override
public void onClick(View v){
listenerForThisRow.onViewClick(thisVersion);
}
}
public interface OnViewClickListener{
void onViewClick(Version version);
}
}
THE FRAGMENT CLASS WHICH HOSTS THE RECYCLER VIEW
public class VersionRecycler extends Fragment {
protected RecyclerView mRecycler;
protected VersionListAdapter mAdapter;
public VersionRecycler(){
super(R.layout.fragment_recycler_versions);
}
#Override
public View onCreateView(
#NotNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState
) {
VersionViewModel mVersionViewModel = new VersionViewModel(requireActivity().getApplication());
long tutorialId = requireArguments().getLong("tutorialId");
View view = inflater.inflate(R.layout.fragment_recycler_versions, container, false);
mAdapter = new VersionListAdapter(requireActivity());
mRecycler = view.findViewById(R.id.versions_rv);
mRecycler.setLayoutManager(new LinearLayoutManager(view.getContext(), LinearLayoutManager.VERTICAL, false));
mVersionViewModel.getByTutorialId(tutorialId).observe(requireActivity(), versions->mAdapter.setElementList(versions));
mRecycler.setAdapter(mAdapter);
return view;
}
}
HOW THE FRAGMENT IS EMBEDDED IN THE ACTIVITY
<LinearLayout
android:id="#+id/layout_versions_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
FRAGMENT LAYOUT
<?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=".versionrecycler.VersionRecycler">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/versions_rv"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="#layout/row_versions_rv"/>
</androidx.constraintlayout.widget.ConstraintLayout>
LAYOUT FOR RECYCLERVIEW ROW
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false">
<Button
android:id="#+id/version_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="40sp"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
You should also add Start and Bottom constraints:
<?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=".versionrecycler.VersionRecycler">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/versions_rv"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:listitem="#layout/row_versions_rv"/>
</androidx.constraintlayout.widget.ConstraintLayout>
You could also change RecyclerView layout_height to wrap_content and add Start constraint only

Getting Problem In RecycleView with TextInputEditText

I am a new Programmer, actually I was trying to make an app. I was trying to make an activity that uses RecyclerView to Show TextInputEditText with spinner and TextView. It means that I was trying to make an activity that uses Recyclerview and In the layout of Recycler View, I have used Text Input Edit Text and Spinner and TextView. I have put these three in a single layout. But the main problem that I facing is that when I launch my app with my code then it remains blank activity it is not showing TextInputEditText nor spinner and nor TextView.
So the conclusion is I want to show [TextInputEditText, Spinner and TextView] in RecyclerView But my code is returning Blank Activity.
Here is my code:-
It is my adapter class:-
public class SpecialHoursAdapter extends RecyclerView.Adapter<SpecialHoursAdapter.SpecialHourHolder> {
// private ArrayList[] mDataSet;
private List<SpecialHorusModal> modal = new ArrayList<>();
private Context context;
public SpecialHoursAdapter(Context context) {
this.context = context;
}
#NonNull
#Override
public SpecialHourHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.special_hours_layout_card, parent, false);
return new SpecialHourHolder(view);
}
#Override
public void onBindViewHolder(#NonNull SpecialHourHolder holder, int position) {
}
#Override
public int getItemCount() {
return modal.size();
}
public static class SpecialHourHolder extends RecyclerView.ViewHolder {
private TextInputEditText editText;
private Spinner spinner;
private TextView textView;
public SpecialHourHolder(#NonNull View itemView) {
super(itemView);
editText = itemView.findViewById(R.id.special_hours_editor);
spinner = itemView.findViewById(R.id.spinner_special_hours_date);
textView = itemView.findViewById(R.id.time_picker_special_horus);
}
}
}
It is My MainActivity:-
public class SpecialHoursActivity extends AppCompatActivity {
private RecyclerView containerRecyclerView;
private RecyclerView.LayoutManager first, container;
private SpecialHoursAdapter adapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_special_horus);
// mainRecyclerView = findViewById(R.id.activity_special_horus_main_recyclerview);
containerRecyclerView = findViewById(R.id.layout_container_recyclerview_special_hours);
// mainRecyclerView.setHasFixedSize(true);
containerRecyclerView.setHasFixedSize(true);
first = new LinearLayoutManager(this);
container = new LinearLayoutManager(this);
// mainRecyclerView.setLayoutManager(first);
containerRecyclerView.setLayoutManager(container);
containerRecyclerView.setAdapter(adapter);
}
}
Here is my RecyclerView Layout:-
<?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="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/special_hours_editor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter Special Hours"
android:inputType="text"
android:maxLength="20" />
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Spinner
android:id="#+id/spinner_special_hours_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/time_picker_special_horus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:gravity="end"
android:text="00:00" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
My Main Layout -
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/activity_special_horus_main_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:scrollbars="vertical">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="#+id/layout_container_recyclerview_special_hours"
android:orientation="vertical"
android:scrollbars="vertical">
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
I have not used any modal class because I don't know how to use it with Widgets.
you need to pass the data to your adapter
public SpecialHoursAdapter(Context context,List<SpecialHorusModal> data) {
this.context = context;
this.model=data; //it will show your recyclerview
}
we could not show the Recyclerview with empty data
You need to populate the data your Adapter holds, adapter with empty data will obviously show no items.
public class SpecialHoursAdapter extends RecyclerView.Adapter<SpecialHoursAdapter.SpecialHourHolder> {
private List<SpecialHorusModal> items = new ArrayList<>();
private Context context;
public SpecialHoursAdapter(Context context) {
this.context = context;
}
//Call this in onClick of your button, passing it the object to add
public void addItem(SpecialHoursModal item) {
items.add(item);
notifyDataSetChange(); //This is important
}
#NonNull
#Override
public SpecialHourHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.special_hours_layout_card, parent, false);
return new SpecialHourHolder(view);
}
#Override
public void onBindViewHolder(#NonNull SpecialHourHolder holder, int position) {
//Bind the data to view for the object at this position
SpecialHorusModal item = items.get(position);
//...
}
#Override
public int getItemCount() {
return items.size();
}
public static class SpecialHourHolder extends RecyclerView.ViewHolder {
private TextInputEditText editText;
private Spinner spinner;
private TextView textView;
public SpecialHourHolder(#NonNull View itemView) {
super(itemView);
editText = itemView.findViewById(R.id.special_hours_editor);
spinner = itemView.findViewById(R.id.spinner_special_hours_date);
textView = itemView.findViewById(R.id.time_picker_special_horus);
}
}
}
When your button is clicked, or you need to add an item:
adapter.addItem(new SpecialHorusModal(...));

ListView CustomAdapter not showing first position results

I'm new to Android Studio and coding in general and I am trying to display a custom ListView with an image of a colour and the name of the colour. I have used a custom Adapter to inflate the view with two arrays containing the drawable image colours and string of the names.
The problem I am having - the custom adapter is only displaying the layers from position 1 and onwards. For example, where the first layer should be img_01 and "red" - it is displaying img_02 and "Orange".
I've tried debugging the code and it seems that though the adapter is setting the values for position 0, but I cannot find the reason why it is not displaying (as the others are displaying fine).
The images & names are just placeholders, so an alternative solution that doesn't include both the drawables and names wouldn't be viable,
Thank you in advance
CustomAdapter.java
public class CustomAdapter extends BaseAdapter {
Context context;
int[] images;
String[] colour;
LayoutInflater mInflater;
public CustomAdapter(Context c, int[] i, String[] col) {
this.context = c; //sets the application context that has been passed to the adapter
this.images = i; //sets the images array that has been passed to the adapter
this.colour = col; //sets the colour array that has been passed to the adapter
mInflater = (LayoutInflater.from(context)); //sets the layout inflater from context
}
#Override
public int getCount() { //total number of elements in the array
return images.length;
}
#Override
public Object getItem(int position) { //gets the item using the position
return null;
}
#Override
public long getItemId(int position) { //gets the item position
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) { //this is used to update the view
convertView = mInflater.inflate(R.layout.custom_layout, null);
ImageView image = convertView.findViewById(R.id.imageView);
TextView text = convertView.findViewById(R.id.textView);
text.setText(colour[position]);
image.setImageResource(images[position]);
return convertView;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
ListView mListView;
int[] images = {R.drawable.img01,
R.drawable.img02,
R.drawable.img03,
R.drawable.img04};
String[] colour = {"Red",
"Orange",
"Yellow",
"Green"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = findViewById(R.id.listView);
CustomAdapter customAdapter = new CustomAdapter(getApplicationContext(), images, colour);
//passes information of images and application context to the item adapter
mListView.setAdapter(customAdapter);
//sets the adapter to the listview
}
}
custom_layout.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"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginStart="7dp"
android:layout_marginLeft="7dp"
android:layout_marginTop="9dp"
app:srcCompat="#drawable/img01" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginStart="99dp"
android:layout_marginLeft="99dp"
android:layout_marginTop="36dp"
android:text="colourName" />
</RelativeLayout>
activity_main.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=".MainActivity">
<ListView
android:id="#+id/listView"
android:layout_width="409dp"
android:layout_height="729dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Try to set the height of the ListView to wrap_content instead of hardcoding it
<ListView
...
android:layout_height="wrap_content"/>
You can do it with RecyclerView.
Create a custom class
public class ExampleItem {
private int mImageResource; //your color image
private String mText1; //your text
public ExampleItem(int imageResource, String text1) {
mImageResource = imageResource;
mText1 = text1;
}
public int getImageResource() {
return mImageResource;
}
public String getText1() {
return mText1;
}
}
Create a XML layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
app:cardCornerRadius="4dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp">
<ImageView
android:id="#+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="2dp" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toEndOf="#+id/imageView"
android:text="Line 1"
android:textColor="#android:color/black"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
</android.support.v7.widget.CardView>
Create a Recycler View Adapter
public class ExampleAdapter extends RecyclerView.Adapter<ExampleAdapter.ExampleViewHolder> {
private ArrayList<ExampleItem> mExampleList;
public static class ExampleViewHolder extends RecyclerView.ViewHolder {
public ImageView mImageView;
public TextView mTextView1;
public ExampleViewHolder(View itemView) {
super(itemView);
mImageView = itemView.findViewById(R.id.imageView);
mTextView1 = itemView.findViewById(R.id.textView);
}
}
public ExampleAdapter(ArrayList<ExampleItem> exampleList) {
mExampleList = exampleList;
}
#Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.example_item, parent, false);
ExampleViewHolder evh = new ExampleViewHolder(v);
return evh;
}
#Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
ExampleItem currentItem = mExampleList.get(position);
holder.mImageView.setImageResource(currentItem.getImageResource());
holder.mTextView1.setText(currentItem.getText1());
}
#Override
public int getItemCount() {
return mExampleList.size();
}
}
your activity_main.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"
tools:context="com.example.application.recyclerviewproject.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray"
android:padding="4dp"
android:scrollbars="vertical" />
</RelativeLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<ExampleItem> exampleList = new ArrayList<>();
exampleList.add(new ExampleItem(R.drawable.img01, "Red"));
exampleList.add(new ExampleItem(R.drawable.img02, "Orange"));
exampleList.add(new ExampleItem(R.drawable.img03, "Yellow"));
exampleList.add(new ExampleItem(R.drawable.img04, "Green"));
mRecyclerView = findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mAdapter = new ExampleAdapter(exampleList);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
}

Application keeps crashing with "E/RecyclerView: No adapter attached; skipping layout"

My application keeps crashing whenever I try to open up the layout with a RecyclerView.
Apparently, I am getting this error:
E/RecyclerView: No adapter attached; skipping layout
The code was mostly copied from the documentation.
MyAdapter.java
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private String[] mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class MyViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView textView;
public MyViewHolder(TextView v) {
super(v);
textView = v;
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
TextView v = (TextView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.textView.setText(mDataset[position]);
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.length;
}
}
ChatActivity.java
public class ChatActivity extends AppCompatActivity{
private RecyclerView recyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager layoutManager;
String[] myDataset = {"Hello", "Who r u", "Wait what", "Nice to meet you", "Yeet"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true);
// use a linear layout manager
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
// specify an adapter (see also next example)
mAdapter = new MyAdapter(myDataset);
recyclerView.setAdapter(mAdapter);
}
}
activity_chat.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/btnFinish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/back_button"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
my_text_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:id="#+id/textView" />
</LinearLayout>
Your my_text_view.xml should contain the TextView as root element according your implementation.
Approach-1:
So, just change this like below solve your problem.
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="30dp"
android:id="#+id/textView" />
Approach-2:
Or change your onCreateViewHolder implementation:
onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.my_text_view, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
And change ViewHolder also:
MyViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView textView;
public MyViewHolder(View v) {
super(v); textView = v;
textView = v.findViewById(R.id.textView);
}
}

LinearLayout within Recyclerview, within another LinearLayout within another RecyclerView

Good morning, I have a problem trying to link a Recyclerview with another Recyclerview, I mean one within others, the first recyclerview is in my activity, which in turn is filler for a second recyclerview, which is in a LinearLayout, since Once that recyclerview is filled by another layout that has an ImageView and a TextView, the problem is that I can not use the two recycler view since the app stops, but if I use the layout separately if they work in the same way, I know if I explain, I have 3 layouts which are:
The problem is that I can not use both recycler view since the app stops, but if I use the layout separately if they work in the same way, I do not know if I explain myself, I have 3 layouts, the one in the activity that contains a recyclerview, the container of the elements that contains the second recyclerview and a texview, and finally the layout portraitLayout that contains an imageView and a texView, if I only use the layout of the activity, the second one is rendered well but without any image, and if I remove the layout of the activity and leave the second with the third this is rendered with their respective images.
I have 2 adapters which are:
AdapterPortrait:
`public class Adapter_Portrait extends RecyclerView.Adapter<Adapter_Portrait.ViewHolder> {
private List<Portrait> portraits;
private int layout;
private OnItemClickListener listener;
private Context context;
public Adapter_Portrait(List<Portrait> portraits, int layout, OnItemClickListener listener) {
this.portraits = portraits;
this.layout = layout;
this.listener = listener;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v= LayoutInflater.from(parent.getContext()).inflate(this.layout,parent,false);
ViewHolder vh=new ViewHolder(v);
context=parent.getContext();
return vh;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.bind(portraits.get(position),this.listener);
}
#Override
public int getItemCount() {
return portraits.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
TextView textView;
public ViewHolder(View itemView) {
super(itemView);
this.imageView = itemView.findViewById(R.id.imagePortrait);
this.textView = itemView.findViewById(R.id.textNamePortrait);
}
public void bind(final Portrait portrait, final OnItemClickListener listener){
this.textView.setText(portrait.getName_portrait());
Picasso.with(context).load(portrait.getImagePortrait()).fit().into(imageView);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
listener.onItemClick(portrait, getAdapterPosition());
}
});
}
}
public interface OnItemClickListener{
void onItemClick(Portrait portrait, int position);
}
}`
AdapterList_Pieces:
`public class AdapterList_Pieces extends
RecyclerView.Adapter<AdapterList_Pieces.ViewHolder> {
private List<Artist> artists;
private int layout;
private OnItemClickListener listener;
private Context context;
public AdapterList_Pieces(List<Artist> artists, int layout, OnItemClickListener listener) {
this.artists = artists;
this.layout = layout;
this.listener = listener;
}
public class ViewHolder extends RecyclerView.ViewHolder{
RecyclerView recyclerView;
TextView textView;
public ViewHolder(View itemView) {
super(itemView);
this.recyclerView = itemView.findViewById(R.id.RecyclerViewPieces);
this.textView = itemView.findViewById(R.id.textViewPieces);
}
public void bind(final Artist artist, final OnItemClickListener listener){
this.textView.setText(artist.getName_artist());
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
listener.onItemClick(artist, getAdapterPosition());
}
});
}
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v= LayoutInflater.from(parent.getContext()).inflate(this.layout,parent,false);
ViewHolder vh=new ViewHolder(v);
context=parent.getContext();
return vh;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.bind(artists.get(position),this.listener);
}
#Override
public int getItemCount() {
return artists.size();
}
public interface OnItemClickListener{
void onItemClick(Artist artist, int position);
}
}`
My Activity is:
public class PiecesActivity extends AppCompatActivity {
List<Artist> artists;
List<Portrait> portraits;
RecyclerView recyclerView;
RecyclerView recyclerViewPiece;
RecyclerView.Adapter rAdapter;
RecyclerView.LayoutManager layoutManagerPiece;
RecyclerView.Adapter AdapterPiece;
RecyclerView.LayoutManager layoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.portraitcontenetorslayout);
recyclerView= findViewById(R.id.recyclerViewListPieces);
recyclerViewPiece= findViewById(R.id.RecyclerViewPieces);
artists= ConsultingInformation.getArtist();
portraits= ConsultingInformation.getPortrait();
layoutManager = new LinearLayoutManager(this);
layoutManagerPiece = new LinearLayoutManager(this);
rAdapter= new Adapter_Portrait(portraits,R.layout.portraitlayout, new Adapter_Portrait.OnItemClickListener(){
#Override
public void onItemClick(Portrait portrait, int position) {
Toast.makeText(PiecesActivity.this, "This piece is "+ portraits.get(position).getName_portrait(), Toast.LENGTH_LONG).show();
}
});
recyclerViewPiece.setHasFixedSize(true);
recyclerViewPiece.setItemAnimator(new DefaultItemAnimator());
recyclerViewPiece.setLayoutManager(layoutManagerPiece);
recyclerViewPiece.setAdapter(rAdapter);
AdapterPiece= new AdapterList_Pieces(artists,R.layout.portraitcontenetorslayout, new AdapterList_Pieces.OnItemClickListener(){
#Override
public void onItemClick(Artist artist, int positionArt) {
Toast.makeText(PiecesActivity.this, "This list of pieces is "+ artists.get(positionArt).getName_artist(), Toast.LENGTH_LONG).show();
}
});
recyclerView.setHasFixedSize(true);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(AdapterPiece);
}
}`
I had read that it was not possible to put a list downloadble within another, but i did not get an unstable method for my case that are two list of objects one within another.
My layouts just in case.
PortraitLayout:
<?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="wrap_content">
<ImageView
android:id="#+id/imagePortrait"
android:layout_width="78dp"
android:layout_height="63dp"
android:layout_marginLeft="25dp"
android:textAlignment="center"
android:contentDescription="TODO"
android:layout_marginStart="25dp" />
<TextView
android:id="#+id/textNamePortrait"
android:layout_width="225dp"
android:layout_height="30dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:text="TextView"
android:layout_marginStart="10dp" />
</LinearLayout>
portraitcontenetorlayout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/textViewPieces"
android:layout_width="match_parent"
android:layout_height="35dp"
android:background="#BCBCBC"
android:paddingLeft="7dp"
android:text=" TextView"
android:gravity="center_vertical" />
<android.support.v7.widget.RecyclerView
android:id="#+id/RecyclerViewPieces"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
activitypieces:
<?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">
<TextView
android:id="#+id/textView3"
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="30dp"
android:text="Obras" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerViewListPieces"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

Categories

Resources