In an app I am working on, I am using a Recycler View to show a list of items. I would like the list to display some view (For example, a text view) when the list is empty. I know that with ListViews, one could call setEmptyView, but RecyclerView has no such method.
I have tried setting the visibility of a view to GONE, and making it visible when the RecyclerView dataset is empty, but adding any view to the layout file where the RecyclerView is defined leads to an error:
Attempt to invoke virtual method 'boolean
android.support.v7.widget.RecyclerView$ViewHolder.shouldIgnore()' on a null
object reference
What is the best way to go about what I am doing?
For more info, the RecyclerView is held inside a Fragment, and the layout is inflated in the onCreateView function.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_grocerylist, container, false);
rv = view.findViewById(R.id.grocery_list);
dh = new DatabaseHandler(view.getContext());
dataset = dh.getGroceries();
// Set the adapter
if (view instanceof RecyclerView) {
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view;
recyclerView.setLayoutManager(new LinearLayoutManager(context));
adapter = new GroceryListRecyclerViewAdapter(dataset,mListener,this);
recyclerView.setAdapter(adapter);
}
ItemTouchHelper.Callback callback = new SimpleTouchHelperCallback(adapter);
ith = new ItemTouchHelper(callback);
ith.attachToRecyclerView(rv);
DividerItemDecoration div = new DividerItemDecoration(rv.getContext(),
DividerItemDecoration.VERTICAL);
rv.addItemDecoration(div);
return view;
}
The XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView 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:id="#+id/grocery_list" android:name="com.github.jlcarveth.grocer.layout.fragment.GroceryListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
app:layoutManager="LinearLayoutManager" tools:context="com.github.jlcarveth.grocer.layout.fragment.GroceryListFragment" tools:listitem="#layout/grocery_item"/>
I updated your code:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:name="com.github.jlcarveth.grocer.layout.fragment.GroceryListFragment"
android:layout_width="match_parent"
tools:context="com.github.jlcarveth.grocer.layout.fragment.GroceryListFragment"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/grocery_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
app:layoutManager="LinearLayoutManager"
tools:listitem="#layout/grocery_item" />
<TextView
android:id="#+id/empty_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:visibility="gone"
android:text="NO DATA AVAILABLE" />
</FrameLayout>
Your Fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_grocerylist, container, false);
rv = view.findViewById(R.id.grocery_list);
TextView emptyView = (TextView)view.findViewById(R.id.empty_view);
dh = new DatabaseHandler(view.getContext());
dataset = dh.getGroceries();
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) rv;
recyclerView.setLayoutManager(new LinearLayoutManager(context));
adapter = new GroceryListRecyclerViewAdapter(dataset,mListener,this);
recyclerView.setAdapter(adapter);
ItemTouchHelper.Callback callback = new SimpleTouchHelperCallback(adapter);
ith = new ItemTouchHelper(callback);
ith.attachToRecyclerView(recyclerView);
DividerItemDecoration div = new DividerItemDecoration(recyclerView.getContext(),
DividerItemDecoration.VERTICAL);
recyclerView.addItemDecoration(div);
if (dataset.isEmpty()){
recyclerView.setVisibility(View.GONE);
emptyView.setVisibility(View.VISIBLE);
} else {
recyclerView.setVisibility(View.VISIBLE);
emptyView.setVisibility(View.GONE);
}
return view;
}
Add a textview to your layout. At the same level as the RecyclerView
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
<TextView
android:id="#+id/empty_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:visibility="gone"
android:text="#string/no_data_available" />
At the onCreate or the appropriate callback check to see if the dataset that feeds your RecyclerView is empty. If it is then the RecyclerView is empty too. In that case, the message appears on the screen. If not, change its visibility:
private RecyclerView recyclerView;
private TextView emptyView;
// ...
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
emptyView = (TextView) rootView.findViewById(R.id.empty_view);
// ...
if (dataset.isEmpty()) {
recyclerView.setVisibility(View.GONE);
emptyView.setVisibility(View.VISIBLE);
}
else {
recyclerView.setVisibility(View.VISIBLE);
emptyView.setVisibility(View.GONE);
}
This answer is for developers using Kotlin and databinding in their Android project.
custom_recyclerview_empty_support.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Recycler view -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- Empty view -->
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/empty_text_view"
style="#style/TextAppearance.MaterialComponents.Body1"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#color/white_light"
android:gravity="center"
android:textColor="#color/black_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Empty View" />
<!-- Retry view -->
<androidx.appcompat.widget.LinearLayoutCompat
android:id="#+id/retry_linear_layout_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#color/white_light"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/retry_text_view"
style="#style/TextAppearance.MaterialComponents.Body1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/views_pad_horizontal"
android:layout_marginTop="#dimen/views_pad_vertical"
android:layout_marginEnd="#dimen/views_pad_horizontal"
android:layout_marginBottom="#dimen/views_pad_vertical"
android:gravity="center"
tools:text="Retry View" />
<com.google.android.material.button.MaterialButton
android:id="#+id/retry_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/retry_button" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- Loading view -->
<FrameLayout
android:id="#+id/loading_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#color/white_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ProgressBar
android:id="#+id/progress_bar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
The fragment class where I am using this Custom RecyclerView class
<app.ui.widgets.RecyclerViewEmptySupport
android:id="#+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Creating a Custom RecyclerView class :
class RecyclerViewEmptySupport(context: Context, attrs: AttributeSet) :
ConstraintLayout(context, attrs) {
private val binding: CustomRecyclerviewEmptySupportBinding
val recyclerView: RecyclerView
init {
this.binding =
CustomRecyclerviewEmptySupportBinding.inflate(LayoutInflater.from(context), this, true)
this.recyclerView = binding.recyclerView
}
fun updateViews(
loading: Boolean = false,
retry: Boolean = false,
empty: Boolean = false,
success: Boolean = false
) {
binding.recyclerView.setVisibleOrGone(success)
binding.emptyTextView.setVisibleOrGone(empty)
binding.retryLinearLayoutView.setVisibleOrGone(retry)
binding.loadingView.setVisibleOrGone(loading)
}
// Empty view
fun showEmptyMessage(message: String) {
updateViews(empty = true)
binding.emptyTextView.text = message
}
// Retry view
fun showRetryView(message: String, callback: () -> Unit) {
updateViews(retry = true)
binding.retryTextView.text = message
binding.retryButton.setOnClickListener { callback() }
}
}
The Fragment/Activity class can manage the Views visibility and setting data to views , like this :
When api is to be called , call this block of code ,
binding.myRecyclerView.updateViews(loading = true)
getDataFromRepository()
When data is empty in api response , call this,
binding.myRecyclerView.showEmptyMessage("No Items Message")
When data exists in api , call this ,
list.addAll(apiList)
adapter.notifyDataSetChanged()
binding.myRecyclerView.updateViews(success = true)
When there is some error in api response , call this
binding.myRecyclerView.showRetryView("Unable to get data at the moment.") { getDataFromRepository() }
Why don't you go for a Relative layout.
<Relative layout>
<Recycler View/>
<Text View/>
</Relative layout
As the array is empty
RecyclerView.GONE
TextView.VISIBLE
and if the array is having some data
RecyclerView.VISIBLE
TextView.GONE
In my case, I am following this only.
If doesn't work, I'll send you my code.
When I faced this issue, while surfing the web I found useful gist https://gist.github.com/sheharyarn/5602930ad84fa64c30a29ab18eb69c6e.
Here shown how to implement empty view in elegant way by defining data observer.
Related
I have used two Fragment in my code. I have to display a custom ListView in each fragment. But I would like to handle Button's onClickListener event which is in this ListView.
I can't find online how to use these Button (ImageButton, actually) components in Fragment class.
Here is my code:
My fragment class:
public class tabtodo extends Fragment implements View.OnClickListener {
public tabtodo() {}
private View view, view2;
private ListView lstTask;
private ImageButton btndelete;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_tabtodo, container, false);
lstTask = (ListView) view.findViewById(R.id.listView);
AlUpdater alUpdater = new AlUpdater(getContext());
lstTask.setAdapter(alUpdater.getAdapterTodo());
view2 = inflater.inflate(R.layout.row, container, false);
btndelete = (ImageButton) view2.findViewById(R.id.btntest);
btnTest.setOnClickListener(this);
return mView;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btntest:
Log.i("prova", "prova ");
break;
default:
Log.i("prova", "def");
break;
}
}
alUpdater.getAdapterTodo() is:
public ArrayAdapter < String > getAdapterTodo() {
ArrayList < String > taskList = (dG).getListTodo("todo");
if (adptodo == null) {
adptodo = new ArrayAdapter < > (context, R.layout.row, R.id.task_title, taskList);
adptodo.notifyDataSetChanged();
} else {
adptodo.clear();
adptodo.addAll(taskList);
adptodo.notifyDataSetChanged();
}
return adptodo;
}
as you can see, I am using a custom layout for the arrayadapter.
R.layout.fragment_tabtodo: is a fragment with just a listview:
<?xml version="1.0" encoding="utf-8"?>`
<FrameLayout 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"
tools:context=".tabtodo"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:background="#color/white">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#color/white"
android:dividerHeight="0dp"
android:footerDividersEnabled="true"
android:headerDividersEnabled="true">
</ListView>
</FrameLayout>
and finally, the XML of the row of the adapter (**R.layout.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingVertical="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/themeselector">
<TextView
android:id="#+id/task_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginEnd="10dp"
android:text="TASK"
android:textColor="#color/white"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/btnGoToDone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints" />
<ImageButton
android:id="#+id/btnGoToDone"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:backgroundTint="#android:color/transparent"
android:onClick="switchTodoDone"
android:src="#drawable/ic_done_icon"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/btndelete"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="#+id/btndelete"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:backgroundTint="#android:color/transparent"
android:src="#drawable/ic_delete_icon"
android:onClick="deleteTask"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
you need to create a custom adapter for you ListView. and handle the button click there.
check this tutorial here
I would recommend that you use RecyclerView instead of ListView since it enforces the ViewHolder pattern which improves the performance.
Here is my code.i want to put 3 recyclerViews in my layout but it is very slow on device while running. If there is 2 recyclerview it works smooth but if 3 slow very :
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
android:id="#+id/scroll_view"
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"
tools:context=".fragments.MainFragment">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:textColor="#color/blacker"
android:textStyle="bold"
android:textSize="18sp"
android:text="Техника для офиса"
android:layout_marginTop="20dp"
android:layout_marginLeft="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp" />
<android.support.v7.widget.RecyclerView
android:nestedScrollingEnabled="false"
android:fillViewport="true"
android:layout_marginBottom="15dp"
android:layout_marginTop="15dp"
android:id="#+id/recyclerView_popular_goods"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
<TextView
android:textColor="#color/blacker"
android:textStyle="bold"
android:textSize="18sp"
android:text="Компьютерная техника"
android:layout_marginTop="20dp"
android:layout_marginLeft="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp" />
<android.support.v7.widget.RecyclerView
android:nestedScrollingEnabled="false"
android:fillViewport="true"
android:layout_marginBottom="15dp"
android:layout_marginTop="15dp"
android:id="#+id/recyclerView_competitive_goods"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
<TextView
android:textColor="#color/blacker"
android:textStyle="bold"
android:textSize="18sp"
android:text="Канцелярские товары"
android:layout_marginTop="20dp"
android:layout_marginLeft="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp" />
<android.support.v7.widget.RecyclerView
android:visibility="gone"
android:fillViewport="true"
android:layout_marginBottom="15dp"
android:layout_marginTop="15dp"
android:id="#+id/recyclerView_stationery_goods"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
</LinearLayout>
Please if somebody had such kind of problem please help me to fix my issue.
I tried Nested scrollview and setNestedScrollingEnabled = false.but nothing helps
Here is my Activity
#SuppressLint("ValidFragment")
public class MainFragment extends BasicFragment implements
MainFragmentView, PopularGoodsAdapter.ProductListener {
#BindView(R.id.scroll_view)
NestedScrollView mScrollView;
#BindView(R.id.recyclerView_stationery_goods)
RecyclerView mRecyclerViewStationeryGoods;
#BindView(R.id.recyclerView_popular_goods)
RecyclerView mRecyclerViewPopularGoods;
#BindView(R.id.recyclerView_competitive_goods)
RecyclerView mRecyclerViewCompetitiveGoods;
#BindView(R.id.imageSlider)
SliderView mSliderView;
#Inject
Navigator mNavigator;
#Inject
#Named(DISPLAY_WIDTH)
int mDisplayWidth;
#InjectPresenter
MainFragmentPresenter mPresenter;
List<Product> list1;
List<Product> list2;
List<Product> list3;
private PopularGoodsAdapter mAdapterPopularGoods;
private PopularGoodsAdapter mAdapterPopularGoods2;
private PopularGoodsAdapter mAdapterPopularGoods3;
private LayoutAnimationController layoutAnimationController;
private List<String> images;
#SuppressLint("ValidFragment")
public MainFragment() {
}
private void initView(View view) {
ButterKnife.bind(this,view);
images = new LinkedList<>();
images.add("https://images.pexels.com/photos/747964/pexels-photo-747964.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260");
images.add("https://images.pexels.com/photos/929778/pexels-photo-929778.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260");
images.add("https://images.pexels.com/photos/218983/pexels-photo-218983.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260");
mSliderView.setSliderAdapter(new SliderAdapterExample(getContext(), images, "mainPage"));
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
LinearLayoutManager layoutManager2 = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
LinearLayoutManager layoutManager3 = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
mRecyclerViewPopularGoods.setLayoutManager(layoutManager);
layoutAnimationController = AnimationUtils.loadLayoutAnimation(getContext(),R.anim.layout_item_from_left);
list1 = new LinkedList<>();
mRecyclerViewPopularGoods.setLayoutAnimation(layoutAnimationController);
mRecyclerViewCompetitiveGoods.setLayoutManager(layoutManager2);
list2 = new LinkedList<>();
mRecyclerViewCompetitiveGoods.setLayoutAnimation(layoutAnimationController);
mRecyclerViewStationeryGoods.setLayoutManager(layoutManager3);
list3 = new LinkedList<>();
mRecyclerViewStationeryGoods.setLayoutAnimation(layoutAnimationController);
mRecyclerViewPopularGoods.setAdapter(mAdapterPopularGoods = new PopularGoodsAdapter(getContext(),list1,mDisplayWidth,"popular",this));
mRecyclerViewCompetitiveGoods.setAdapter(mAdapterPopularGoods2 = new PopularGoodsAdapter(getContext(),list2,mDisplayWidth,"competitive",this));
mRecyclerViewStationeryGoods.setAdapter(mAdapterPopularGoods3 = new PopularGoodsAdapter(getContext(),list3,mDisplayWidth,"stationery",this));
mRecyclerViewPopularGoods.setNestedScrollingEnabled(false);
mRecyclerViewCompetitiveGoods.setNestedScrollingEnabled(false);
mRecyclerViewStationeryGoods.setNestedScrollingEnabled(false);
getLoadingDialog().showDialog(getFragmentManager());
mPresenter.GET_TOP_HOME_VIEW();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container,
false);
initView(view);
return view;
}
#OnClick({R.id.item_sellers,
R.id.item_price_request,R.id.item_price_competitions})
void Onclick(View view) {
switch (view.getId()) {
case R.id.item_sellers:
mNavigator.toSellersActivty(getContext());
break;
case R.id.item_price_request:
mNavigator.toPriceRequestActivty(getContext());
break;
case R.id.item_price_competitions:
mNavigator.toCompetitionsActivty(getContext());
break;
}
}
#Override
public void initTopHomeView(List<HomeViewObject> result) {
if (null != result ) {
if (result.size() >= 1 && null != result.get(0)) {
list1.addAll(result.get(0).getTopProducts());
mAdapterPopularGoods.notifyDataSetChanged();
mRecyclerViewPopularGoods.setLayoutAnimation(layoutAnimationController);
}
if (result.size() >= 2 && null != result.get(1)) {
list2.addAll(result.get(1).getTopProducts());
mAdapterPopularGoods2.notifyDataSetChanged();
mRecyclerViewPopularGoods.setLayoutAnimation(layoutAnimationController);
}
if (result.size() >= 3 && null != result.get(2)) {
list3.addAll(result.get(2).getTopProducts());
mAdapterPopularGoods3.notifyDataSetChanged();
mRecyclerViewStationeryGoods.setLayoutAnimation(layoutAnimationController);
}
}
}
#Override
public void stopProgress() {
getLoadingDialog().hideDialog();
}
#Override
public void onProductClicked(Product product) {
mNavigator.toProductActivity(getContext(),product);
}
}
Is there any mistake?
Try the following -
Try to put all the views inside NestedScrollView i.e, root view.
Set recyclerView.setNestedScrollingEnabled(false); for both the recyclerViews in your xml.
Change your recycler view's android:layout_height="match_parent" to android:layout_height="wrap_content" and then use Nested scrollView with recyclerView.setNestedScrollingEnabled(false);
try to change your ScrollView with NestedScrollViewand Change your recycler view's android:layout_height="match_parent" to android:layout_height="wrap_content" :
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
android:id="#+id/scroll_view"
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"
tools:context=".fragments.MainFragment">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:textColor="#color/blacker"
android:textStyle="bold"
android:textSize="18sp"
android:text="Техника для офиса"
android:layout_marginTop="20dp"
android:layout_marginLeft="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp" />
<android.support.v7.widget.RecyclerView
android:nestedScrollingEnabled="false"
android:fillViewport="true"
android:layout_marginBottom="15dp"
android:layout_marginTop="15dp"
android:id="#+id/recyclerView_popular_goods"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:textColor="#color/blacker"
android:textStyle="bold"
android:textSize="18sp"
android:text="Компьютерная техника"
android:layout_marginTop="20dp"
android:layout_marginLeft="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp" />
<android.support.v7.widget.RecyclerView
android:nestedScrollingEnabled="false"
android:fillViewport="true"
android:layout_marginBottom="15dp"
android:layout_marginTop="15dp"
android:id="#+id/recyclerView_competitive_goods"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:textColor="#color/blacker"
android:textStyle="bold"
android:textSize="18sp"
android:text="Канцелярские товары"
android:layout_marginTop="20dp"
android:layout_marginLeft="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp" />
<android.support.v7.widget.RecyclerView
android:visibility="gone"
android:fillViewport="true"
android:layout_marginBottom="15dp"
android:layout_marginTop="15dp"
android:id="#+id/recyclerView_stationery_goods"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
and :
RecyclerView recycleView1 = (RecyclerView) findViewById(R.id.recyclerView_popular_goods);
RecyclerView recycleView2 = (RecyclerView) findViewById(R.id.recyclerView_competitive_goods);
RecyclerView recycleView3 = (RecyclerView) findViewById(R.id.recyclerView_stationery_goods);
recycleView1.setNestedScrollingEnabled(false);
recycleView2.setNestedScrollingEnabled(false);
recycleView3.setNestedScrollingEnabled(false);
If your devices API is below v 21, use the following:
ViewCompat.setNestedScrollingEnabled(recycleView1, false);
ViewCompat.setNestedScrollingEnabled(recycleView2, false);
ViewCompat.setNestedScrollingEnabled(recycleView3, false);
Your design needs to change. As soon as you're adding RecyclerView with nested scrolling disabled, you should keep in mind that view will have its items created all at once.
It basically means no typical RecyclerView optimization magic when only needed amount of items is created and rendered, then reused, based on screen real estate etc.
In your case the situation is even less good as you have 3 such RecyclerViews. The performance of your solution will of course depend on hardware and number of items inside each RecyclerView, but pls do consider using just ONE RecyclerView and no ScrollView at all.
Finally I achieved.I used NestedScrollView as root.And used only 1 recyclerview.And in adapter of this recyclerview I created other recyclerViews.Scrolling smooth Thanks #Venky
I have three horizontal scrolling recycler views that are too large vertically for the app screen. To solve this, I nested them inside a NestedScrollView however the vertical scroll doesn't go all the way to the bottom of the last recycler view.
This is as far as the view will scroll:
Here's my config:
Container View:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
android:id="#+id/recyclerTop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="#layout/recycler_with_filters"/>
<include
android:id="#+id/recyclerMiddle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="#layout/recycler_with_filters"/>
<include
android:id="#+id/recyclerBottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="#layout/recycler_with_filters"/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
Included layout:
<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">
<TextView
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:text="Test!"
android:textColor="#color/colorPrimaryDark"
android:textSize="24sp"
app:fontFamily="#font/didot"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="#+id/filters"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:orientation="horizontal"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#id/header">
<Button
android:id="#+id/filter1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/btn_filter_inactive"
android:textColor="#color/colorPrimaryDark"
android:text="filter1" />
<Button
android:id="#+id/filter2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/btn_filter_inactive"
android:textColor="#color/colorPrimaryDark"
android:text="filter2" />
<Button
android:id="#+id/filter3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/btn_filter_inactive"
android:textColor="#color/colorPrimaryDark"
android:text="filter3" />
<Button
android:id="#+id/filter4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/btn_filter_inactive"
android:textColor="#color/colorPrimaryDark"
android:text="filter4" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:scrollbars="vertical"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#id/filters" />
</androidx.constraintlayout.widget.ConstraintLayout>
Controller:
public class TestRecyclerFragment extends Fragment {
public static TestRecyclerFragment newInstance() {
return new TestRecyclerFragment();
}
private RecyclerView mRecyclerViewTop;
private RecyclerView mRecyclerViewMiddle;
private RecyclerView mRecyclerViewBottom;
private RecyclerView.Adapter mAdapterTop;
private RecyclerView.Adapter mAdapterMiddle;
private RecyclerView.Adapter mAdapterBottom;
private Business[] mBusinesses = {new Business("The Tavern", 0), new Business("The Tavern1", 0), new Business("The Tavern2", 0), new Business("The Tavern3", 0), new Business("The Tavern4", 0), new Business("The Tavern5", 0), new Business("The Tavern6", 1), new Business("The Tavern7", 1), new Business("The Tavern8", 1), new Business("The Tavern9", 1), new Business("The Tavern10", 1), new Business("The Tavern11", 1)};
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_test_recycler, container, false);
View recycleWithFilterTop = v.findViewById(R.id.recyclerTop);
mRecyclerViewTop = recycleWithFilterTop.findViewById(R.id.recycler_view);
View recycleWithFilterMiddle = v.findViewById(R.id.recyclerMiddle);
mRecyclerViewMiddle = recycleWithFilterMiddle.findViewById(R.id.recycler_view);
View recycleWithFilterBottom = v.findViewById(R.id.recyclerBottom);
mRecyclerViewBottom = recycleWithFilterBottom.findViewById(R.id.recycler_view);
mRecyclerViewTop.setHasFixedSize(true);
mRecyclerViewMiddle.setHasFixedSize(true);
mRecyclerViewBottom.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManagerTop = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
mRecyclerViewTop.setLayoutManager(layoutManagerTop);
RecyclerView.LayoutManager layoutManagerMiddle = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
mRecyclerViewMiddle.setLayoutManager(layoutManagerMiddle);
RecyclerView.LayoutManager layoutManagerBottom = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
mRecyclerViewBottom.setLayoutManager(layoutManagerBottom);
mAdapterTop = new TestRecyclerFragment.TestAdapter(mBusinesses);
mRecyclerViewTop.setAdapter(mAdapterTop);
mAdapterMiddle = new TestRecyclerFragment.TestAdapter(mBusinesses);
mRecyclerViewMiddle.setAdapter(mAdapterMiddle);
mAdapterBottom = new TestRecyclerFragment.TestAdapter(mBusinesses);
mRecyclerViewBottom.setAdapter(mAdapterBottom);
return v;
}
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyViewHolder> {
private Business[] businesses;
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView mBusinessName;
public MyViewHolder(View v) {
super(v);
mBusinessName = itemView.findViewById(R.id.businessName);
}
}
public TestAdapter(Business[] myDataset) {
mBusinesses = myDataset;
}
#Override
public TestAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.view_holder_businesses, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.mBusinessName.setText(mBusinesses[position].getName());
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mBusinesses.length;
}
#Override
public int getItemViewType(int position) {
return mBusinesses[position].getViewType();
}
}
}
*Edit: I think the issue has to do with the scroll not knowing how large the view is going to be at the time it draws the view. I've tried hard-coding the heights in the include like this:
<include
android:id="#+id/recyclerTop"
android:layout_width="match_parent"
android:layout_height="400dp"
layout="#layout/recycler_with_filters"/>
However that messes up the view.
*Edit2: I've tried many of the solutions advocated in other questions on this topic including setting setting nestedScrollingEnabling to false. These solutions don't work in my instance. I'm not sure if it's a difference in my configuration or that I'm using a newer version of the NestedScrollView api.
Adding static height is not a proper solution considering different screen resolutions in the market. If you want to have multiple Recyclerviews scrolls as a whole inside NestedScrollView you should consider adding android:nestedScrollingEnabled="false" to Recyclerview:
<android.support.v4.widget.NestedScrollView 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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="#dimen/margin_activity_horizontal">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="LinearLayoutManager"
android:nestedScrollingEnabled="false"/>
<android.support.v7.widget.RecyclerView
android:layout_below="#+id/recycler_view_departments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="LinearLayoutManager"
android:nestedScrollingEnabled="false"/>
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>
I've tested your code, it's working perfectly my side, Just I've added below 3 lines of code in TestRecyclerFragment onCreateView method
mRecyclerViewTop.setNestedScrollingEnabled(false);
mRecyclerViewMiddle.setNestedScrollingEnabled(false);
mRecyclerViewBottom.setNestedScrollingEnabled(false);
You can see working demo https://www.dropbox.com/s/zmfmcdjw58cto4q/device-2019-09-05-115921.mp4?dl=0
I was able to get the scroll view to scroll to the bottom by adding a dynamic height to the layout params of my bottom recycler view:
RecyclerView.LayoutManager layoutManagerBottom = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
mRecyclerViewBottom.setLayoutManager(layoutManagerBottom);
final float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (550 * scale + 0.5f);
mRecyclerViewBottom.getLayoutParams().height = pixels;
I want to add horizontal recyclerview at the bottom of fragment. I followed the tutorial and successfully implemented horizontal recyclerview and cardview but after trying all possible answers,horizontal scrolling is not working.
Here is my code :-
XML :-
<RelativeLayout tools:context="com.AlfaCab.Menuactivtiy"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:layout_marginTop="56dp"
android:id="#+id/Mainlayout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="#color/BgColor"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentBottom="true"
android:background="#drawable/offer_white_box">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Offers"
android:gravity="center"
android:textSize="18sp"
android:textColor="#color/BlackTextColor"
android:textStyle="bold"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView_offer"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:scrollbars="none"/>
<!-- android:orientation="horizontal"
android:scrollbars="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
/> -->
</LinearLayout>
</RelativeLayout>
Here is my offer_cardview.xml / custom layout for recyclerview :-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<!-- <!–Offer Start–>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/offer_white_box">
-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!--Offer Coupon-->
<LinearLayout
android:layout_width="140dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/round_box"
>
<LinearLayout
android:id="#+id/ll_offer_bg"
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:background="#drawable/offer_red_box"
android:layout_marginBottom="3dp">
<TextView
android:id="#+id/tv_offer_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Get 30% Cashback"
android:textSize="12sp"
android:textColor="#color/WhiteTextColor"
android:textStyle="bold"
android:layout_gravity="center_vertical"
android:gravity="center"/>
</LinearLayout>
<TextView
android:id="#+id/tv_offer_disc"
android:layout_width="match_parent"
android:layout_height="80dp"
android:text="upto Rs. 300 cashback on Outstation"
android:textSize="10sp"
android:textColor="#color/BlackTextColor"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/>
</LinearLayout>
<!--Offer Coupon Ends-->
</LinearLayout>
<!--</LinearLayout>-->
<!--Offer Ends-->
</android.support.v7.widget.CardView>
</LinearLayout>
HomeFragment.java :-
//a list to store all the products
List<Offer_Data> offerList;
//the recyclerview
RecyclerView recyclerView;
String appOfferId,appOfferTitle,appOfferDes,status;
In onCreate :-
//getting the recyclerview from xml
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView_offer);
After successfully adding data to offerList :-
//creating recyclerview adapter
Offer_Adapter adapter = new Offer_Adapter(getActivity(), offerList);
//adapter.notifyDataSetChanged();
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();// Notify the adapter
Offer_Adapter.java :- (Recyclervire adapter)
public class Offer_Adapter extends RecyclerView.Adapter<Offer_Adapter.ProductViewHolder> {
int[] myImageList;
//this context we will use to inflate the layout
private Context mCtx;
//we are storing all the products in a list
private List<Offer_Data> offerList;
//getting the context and product list with constructor
public Offer_Adapter(Context mCtx, List<Offer_Data> offerList) {
this.mCtx = mCtx;
this.offerList = offerList;
this.myImageList = new int[]{R.drawable.offer_red_box, R.drawable.offer_megento_box, R.drawable.offer_yellow_box};
}
#Override
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.offer_cardview, null);
return new ProductViewHolder(view);
}
#Override
public void onBindViewHolder(ProductViewHolder holder, int position) {
//getting the product of the specified position
Offer_Data product = offerList.get(position);
//binding the data with the viewholder views
holder.tv_offer_title.setText(product.getOffer_title());
holder.tv_offer_disc.setText(product.getOffer_disc());
int random_box = getRandom(myImageList);
holder.ll_offer_bg.setBackgroundResource(random_box);
}
public static int getRandom(int[] array) {
int rnd = new Random().nextInt(array.length);
return array[rnd];
}
#Override
public int getItemCount() {
return offerList.size();
}
class ProductViewHolder extends RecyclerView.ViewHolder {
TextView tv_offer_title, tv_offer_disc;
LinearLayout ll_offer_bg;
public ProductViewHolder(View itemView) {
super(itemView);
tv_offer_title = (TextView) itemView.findViewById(R.id.tv_offer_title);
tv_offer_disc = (TextView) itemView.findViewById(R.id.tv_offer_disc);
ll_offer_bg = (LinearLayout)itemView.findViewById(R.id.ll_offer_bg);
}
}
}
Please, help me to make it scroll horizontally.
LinearLayoutManager linearLayoutManager
= new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(linearLayoutManager);
Found the Problem
Change this line
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
to
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
Problem is that , you are passing wrong context to recycler view manager
Should use getActivity() not getContext()
ALso no need to add this line in xml
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
In a android app, I am using RecyclerView to populate my data. I want to freeze the first row and scroll other rows. I am using slider view in first.
Below is the code :
Slider view,I need to freeze it in the screen,
layout_image_slider.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.daimajia.slider.library.SliderLayout
android:id="#+id/slider"
android:layout_width="match_parent"
android:layout_height="#dimen/slider_height"
custom:indicator_visibility="invisible" />
<com.daimajia.slider.library.Indicators.PagerIndicator
android:id="#+id/custom_indicator"
style="#style/AppTheme.AndroidImageSliderCornerOvalBlue"
android:layout_gravity="bottom|center_horizontal" />
</FrameLayout>
DealAdapter.java
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case SLIDER:
return new ViewHolderSlider(LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_image_slider, null));
case DEAL:
return new ViewHolderDeal(LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_deal_item, null));
default:
return null;
}
}
View binding, AllDealsFragment.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mView = inflater.inflate(R.layout.fragment_all_deals, container, false);
mProgressBar = ProgressBar.getInstance(mView.findViewById(R.id.progress_container));
mREM = new ResponseErrorMessageHandler(mContext, this);
mREM.cancelable(false);
mREM.showCancelButton(true);
getBanners();
RecyclerView mRecyclerView = (RecyclerView) mView.findViewById(R.id.rv_all_deals);
mRecyclerView.setHasFixedSize(true);
StaggeredGridLayoutManager mGridLayoutManager =
new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(mGridLayoutManager);
mDealAdapter = new DealAdapter(mContext, mBanners, mDeals, this);
//Add your adapter to the sectionAdapter
SimpleSectionedRecyclerViewAdapter.Section[] dummy =
new SimpleSectionedRecyclerViewAdapter.Section[mSections.size()];
mSectionedAdapter = new SimpleSectionedRecyclerViewAdapter(
mContext, R.layout.layout_deal_header_item, R.id.tvTitle,mDealAdapter);
mSectionedAdapter.setSections(mSections.toArray(dummy));
//Apply this adapter to the RecyclerView
mRecyclerView.setAdapter(mSectionedAdapter);
fragment_all_deals.xml
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_all_deals"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Updated ::
class ViewHolderSlider extends RecyclerView.ViewHolder {
public SliderLayout mSlider;
public ViewHolderSlider(View itemView) {
super(itemView);
mSlider = (SliderLayout) itemView.findViewById(R.id.slider);
mSlider.setPresetTransformer(SliderLayout.Transformer.ZoomOutSlide);
mSlider.setPresetIndicator(SliderLayout.PresetIndicators.Center_Top);
mSlider.setCustomAnimation(new DescriptionAnimation());
mSlider.setCustomIndicator((PagerIndicator) itemView.findViewById(R.id.custom_indicator));
mSlider.setDuration(5000);
}
}
logs ::
06-12 15:23:49.990 1377-1377/com.syncbridge.colombodeals E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.syncbridge.colombodeals, PID: 1377
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.daimajia.slider.library.SliderLayout.setPresetTransformer(com.daimajia.slider.library.SliderLayout$Transformer)' on a null object reference
at com.syncbridge.colombodeals.adapters.DealAdapter$ViewHolderSlider.<init>(DealAdapter.java:186)
at com.syncbridge.colombodeals.adapters.DealAdapter.onCreateViewHolder(DealAdapter.java:58)
at com.syncbridge.colombodeals.adapters.SimpleSectionedRecyclerViewAdapter.onCreateViewHolder(SimpleSectionedRecyclerViewAdapter.java:69)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6290)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5478)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5363)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5359)
at android.support.v7.widget.LayoutState.next(LayoutState.java:100)
at android.support.v7.widget.StaggeredGridLayoutManager.fill(StaggeredGridLayoutManager.java:1574)
at android.support.v7.widget.StaggeredGridLayoutManager.onLayoutChildren(StaggeredGridLayoutManager.java:684)
at android.sup
Change your two files as:
include Slider view as part of fragment_all_deals.xml. Place it above Recyclerview:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.daimajia.slider.library.SliderLayout
android:id="#+id/slider"
android:layout_width="match_parent"
android:layout_height="#dimen/slider_height"
custom:indicator_visibility="invisible" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_all_deals"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/slider" />
</RelativeLayout>
layout_image_slider.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.daimajia.slider.library.Indicators.PagerIndicator
android:id="#+id/custom_indicator"
style="#style/AppTheme.AndroidImageSliderCornerOvalBlue"
android:layout_gravity="bottom|center_horizontal" />
</FrameLayout>