Mohammed Aouf ZOUAG Mohammed Aouf ZOUAG - 4 months ago 33
Java Question

Embedding a RecyclerView within a custom view

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.

Project view

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)

Run

What am I missing here ?

Answer

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.

Comments