Setting scrollbars property in RecyclerView crashes my app - android

I recently started using RecyclerView replacing older ListView. But whenever I use android:scrollbars="vertical" in android.support.v7.widget.RecyclerView element, my app crashes with the following error:
Attempt to invoke virtual method 'boolean android.support.v7.widget.RecyclerView$LayoutManager.canScrollVertically()' on a null object reference
This is how I'm using RecyclerView:
View rootView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.my_fragment, container, false);
return rootView;
}
protected void onPostExecute(Boolean result) {
RecyclerView rv = (RecyclerView) rootView.findViewById(R.id.recyclerview);
LinearLayoutManager llm = new LinearLayoutManager(context);
rv.setLayoutManager(llm);
RecycleViewAdapter adapter = new RecycleViewAdapter(myRecyclerViewAdapter);
rv.setHasFixedSize(true);
rv.setAdapter(adapter);
}
And this is my_fragment.xml file:
<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/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
Everything works perfectly fine if I don't use android:scrollbars="vertical". Thanks for your help.

When using the RecyclerView you don't really need to specify the scrollbars display; it is the LayoutManager job where you specify if it is Vertical or Horizontal orientation and of course the scrollbar display will automatically change whatever orientation you choose.
//for vertical scrollbar and orientation
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
//for horizontal scrollbar and orientation
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);

Related

Recyclerview has no LayoutManager android studio

I'm trying to implement RecyclerView in my android app but it gives me error
"RecyclerView has no Layoutmanager"
even though I initialize it in my code. My java and xml file:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_list, container, false);
mRecyclerView = rootView.findViewById(R.id.recyclerView);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
mRecyclerView.setLayoutManager(layoutManager);
mAdapter = new CustomAdapter(mDataset);
mRecyclerView.setAdapter(mAdapter);
return rootView;
}
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=".List"
android:background="#color/black">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="495dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"/
</androidx.constraintlayout.widget.ConstraintLayout>
You can't use signal activity for recy.... And main activity . Plz create a new xml file like list_file
Are you sure that added recyclerview dependency into gradle
AndroidX
implementation 'androidx.recyclerview:recyclerview:1.1.0'
Support library
implementation 'com.android.support:recyclerview-v7:28.0.0'

How to resolve a NullPointerException while using RecyclerView?

I am using two RecyclerViews in my app, one in the MainActivity and one in another activity. The one in the MainActivity works fine but the other has a NullPointerException and I don't know where the problem here is.
Here is a code snippet of the second RecyclerView, where the logcat says that there is a Null object reference. I used the same code as the first RecyclerView where everything works.
The error message says that there is a problem in this line: recyclerView.setLayoutManager(layoutManager);
and in this line
initRecyclerViewFriendOverView();
Here is where I implemented my second RecyclerView:
private void initRecyclerViewFriendOverView() {
LinearLayoutManager layoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
RecyclerView recyclerView = findViewById(R.id.recyclerViewFriendOverView);
recyclerView.setLayoutManager(layoutManager);
RecyclerViewAdapterFriendOverView adpater = new RecyclerViewAdapterFriendOverView(mNames, mImageUrls, this);
recyclerView.setAdapter(adpater);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_overview);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
init();
initRecyclerViewFriendOverView();
getImages();
}
Here ist the XML where the second RecyclerView is used:
<?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:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewFreundesUebersicht"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Edit:
The problem was that I called the RecyclerView before initializing it in the onCreate method.
EDIT:
You are including another xml file in your activity using include statement, findViewById() won't be able to find views from included layouts. Give an id to your include statement, find that included view first and then call findViewById () in that view:
In Activity layout file:
<include id="includedRecyclerLayout"
....
</include>
And in your code:
ConstraintLayout includedLayout = findViewById(R.id.inckudedRecyclerLayout);
RecyclerView recyclerview = includedLayout.findViewById(R.id.RECYCLER_VIEW_ID);
If it shows error at recyclerView.setLayoutManager(layoutManager); it means your recyclerView is null. Then you look at where you initialized it:
RecyclerView recyclerView = findViewById(R.id.recyclerViewFreundesUebersicht);
It can be null because of two reasons:
You didn't add the RecyclerView to XML
Your R.id.recyclerViewFreundesUebersicht is referring to a view from another xml
Check your XML and make sure your recyclerview was added to XML and the id you are using here is same as the one used in activity.
Initialize LinearLayoutManager like this
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());

Unable to update views through data binding on Android

I was trying to migrate from ButterKnife to Android data binding.
When using ButterKnife (which is working perfectly fine):
// Called after a network call
public void updateView(MyAdapter adapter, String title) {
toolbar.setTitle(title);
recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
Using Android data binding:
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
binding = MyFragmentBinding.inflate(inflater, container, false);
binding.toolbar.setTitle(R.string.app_name); // this works
return binding.getRoot();
}
// Called after a network call
public void updateView(MyAdapter adapter, String title) {
binding.toolbar.setTitle(title);
binding.recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
binding.recyclerView.setLayoutManager(layoutManager);
binding.recyclerView.setAdapter(adapter);
}
After calling updateView on the later code, the screen goes blank.
I debugged to find out that view remains attached to the Fragment.
Also, if I am updating something inside onCreateView then that works.
Is there anything am I doing wrong?
Layout:
<?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">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:elevation="#dimen/_6sdp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:navigationIcon="#drawable/default_nav_icon_back"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" />
</android.support.design.widget.CoordinatorLayout>
</layout>

Android Recycler View orientation can't be changed to horizontal

Currently I have done the code to implement recyclerview with cards view inside. But when I tried to change the recyclerview's orientation from vertical to horizontal it just doesn't change. Since I put the recyclerview inside a fragment, I don't know if it's because of this. My xml code:
<android.support.v7.widget.RecyclerView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:scrollbars="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"/>
I have tried both of these:
View rootView = inflater.inflate(R.layout.discover_fragment, container, false);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(layoutManager);
and:
View rootView = inflater.inflate(R.layout.discover_fragment, container, false);
LinearLayoutManager layoutManager = new GridLayoutManager(getActivity(), 1, GridLayoutManager.HORIZONTAL, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(layoutManager);

"LayoutManager is already attached to a RecyclerView" error

I am trying to have multiple RecyclerViews in a layout but I get the following error: "LayoutManager is already attached to a RecyclerView"
The Java code is:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_squad, container, false);
Activity parentActivity = getActivity();
final ObservableScrollView scrollView = (ObservableScrollView) view.findViewById(R.id.squad_scrollview);
final RecyclerView gkRecyclerView = (RecyclerView) view.findViewById(R.id.gk_recycler);
final RecyclerView coachRecyclerView = (RecyclerView) view.findViewById(R.id.coach_recycler);
coachRecyclerView.setAdapter(new SquadRecyclerAdapter(parentActivity, getSquadDummyData(0)));
coachRecyclerView.setLayoutManager(new MyLinearLayoutManager(parentActivity, LinearLayoutManager.VERTICAL, false));
coachRecyclerView.setHasFixedSize(false);
gkRecyclerView.setAdapter(new SquadRecyclerAdapter(parentActivity, getSquadDummyData(1)));
gkRecyclerView.setLayoutManager(new MyLinearLayoutManager(parentActivity, LinearLayoutManager.VERTICAL, false));
gkRecyclerView.setHasFixedSize(false);
scrollView.setTouchInterceptionViewGroup((ViewGroup) parentActivity.findViewById(R.id.container));
if (parentActivity instanceof ObservableScrollViewCallbacks) {
scrollView.setScrollViewCallbacks((ObservableScrollViewCallbacks) parentActivity);
}
return view;
}
The XML layout code is:
<com.github.ksoichiro.android.observablescrollview.ObservableScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/squad_scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="#dimen/margin_medium"
>
<LinearLayout
android:id="#+id/squad_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/seasons_scrollview"
android:divider="#drawable/nav_bar_divider"
android:elevation="#dimen/card_elevation"
android:orientation="vertical"
android:showDividers="middle">
<LinearLayout
android:id="#+id/coach_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="#dimen/margin_small"
android:paddingLeft="#dimen/margin_standard"
android:paddingRight="#dimen/margin_standard"
android:paddingTop="#dimen/margin_small">
<TextView
android:id="#+id/squad_coach_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Coach"
android:textSize="#dimen/text_size_standard" />
<android.support.v7.widget.RecyclerView
android:id="#+id/coach_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/margin_small"
android:paddingBottom="#dimen/margin_small"
android:scrollbars="none">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
<LinearLayout
android:id="#+id/gk_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="#dimen/margin_small"
android:paddingLeft="#dimen/margin_standard"
android:paddingRight="#dimen/margin_standard"
android:paddingTop="#dimen/margin_small">
<TextView
android:id="#+id/squad_gk_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Goalkeepers"
android:textSize="#dimen/text_size_standard" />
<android.support.v7.widget.RecyclerView
android:id="#+id/gk_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/margin_small"
android:paddingBottom="#dimen/margin_small"
android:scrollbars="none">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
<LinearLayout
android:id="#+id/def_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="#dimen/margin_small"
android:paddingLeft="#dimen/margin_standard"
android:paddingRight="#dimen/margin_standard"
android:paddingTop="#dimen/margin_small">
<TextView
android:id="#+id/squad_def_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Defense"
android:textSize="#dimen/text_size_standard" />
</LinearLayout>
<LinearLayout
android:id="#+id/mid_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="#dimen/margin_small"
android:paddingLeft="#dimen/margin_standard"
android:paddingRight="#dimen/margin_standard"
android:paddingTop="#dimen/margin_small">
<TextView
android:id="#+id/squad_mid_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Midfielders"
android:textSize="#dimen/text_size_standard" />
</LinearLayout>
<LinearLayout
android:id="#+id/for_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="#dimen/margin_small"
android:paddingLeft="#dimen/margin_standard"
android:paddingRight="#dimen/margin_standard"
android:paddingTop="#dimen/margin_small">
<TextView
android:id="#+id/squad_for_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Forwards"
android:textSize="#dimen/text_size_standard" />
</LinearLayout>
</LinearLayout>
</com.github.ksoichiro.android.observablescrollview.ObservableScrollView>
The MyLinearLayoutManager is a custom LinearLayoutManager I found online in order to solve the wrap-content issue of the SDK LinearLayoutManager.
Is there any way I can have multiple RecyclerViews in a single layout? It seems that I cannot attach more than one LayoutManagers per layout.
Any assistance would be very welcome :)
I had this problem too. My Activity uses Tabs, with three fragments, when I go to third tab, and back to first (or second), this error is thrown.
After searching a lot, I found out that may be the garbage collector, because I was using a strong reference.
Since the constructor LinearLayoutManager uses the activity as the parameter (not the fragment), a Tabs Activity stays active during tabs changes.
Removing the local field in mLinearLayoutManager from the class, and using a weak reference, I could get rid of this problem:
before:
public class MyFragment1 extends Fragment
private LinearLayoutManager linearLayoutManager;
#Override
public void onCreate(Bundle savedInstanceState) {
linearLayoutManager = new LinearLayoutManager(getActivity());
(...)
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
(...)
mRecyclerView.setLayoutManager(linearLayoutManager);
}
}
I changed to:
public class MyFragment1 extends Fragment {
// private LinearLayoutManager linearLayoutManager;
#Override
public void onCreate(Bundle savedInstanceState) {
// linearLayoutManager = new LinearLayoutManager(getActivity());
(...)
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
(...)
mRecyclerView.setLayoutManager(
new LinearLayoutManager(getActivity()));
}
}
Just need to create a new instance:
RecyclerView recyclerView = new RecyclerView(getContext());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()))
I faced this error when providing LayoutManager via Dagger. The solution is to replace layout manager injection with layout manager javax.inject.Provider injection.
#Inject
lateinit var layoutManager: Provider<RecyclerView.LayoutManager>
...
recyclerView.setLayoutManager(layoutManager.get())
I have the same problem as well. I work around it by setting null to LinearLayoutManager instance.
public class MyFragment extends Fragment {
protected LinearLayoutManager mLinearLayoutManager;
...
#Override
public void onDestroy() {
super.onDestroy();
if(mLinearLayoutManager != null) // Workaround: android.support.v7.widget.LinearLayoutManager is already attached to a RecyclerView
mLinearLayoutManager = null;
}
I opened FragmentB from FragmentA. Then returned back to FragmentA and got this exception. I found an error. I created in onCreate:
linearLayoutManager = LinearLayoutManager(requireContext())
and used in it onCreateView:
view.recycler_view.layoutManager = linearLayoutManager
Because linearLayoutManager hadn't recreated when we returned from FragmentB, RecyclerView used an old linearLayoutManager. So, I moved linearLayoutManager = LinearLayoutManager(requireContext()) to onCreateView.
In my case, I had declared a LinearLayoutManager globally and I was trying to attach the same instance of LinearLayoutManager to multiple RecyclerView's so I was getting this error.
The Solution is to attach different LayoutManager to each RecyclerView because one LayoutManager can only be attached to one Recyclerview.
I had this problem with Dagger2 and it was solved by removing the Scope Annotation.
I had annotated the code with some scope and when i removed the scope the problem was fixed.
I hope this would be helpful to you.
#MyScope #Provides static LinearLayoutManager provideLinearLayoutManager
I deleted the #MyScope.
This error I faced with Daggar2
and simply remove by using Provider before the LinearLayoutManager like;
#Inject
Provider <LinearLayoutManager> linearLayoutManager;
mViewDataBinding.rvResult.setLayoutManager(linearLayoutManager.get());
Possible options to fix this crash:
Create an instance of LayoutManager in onViewCreated of Fragment:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recyclerView.layoutManager = LinearLayoutManager(context)
}
If it is necessary to have an instance of LayoutManager as a variable in Fragment, then detach the instance from RecyclerView in onDestroyView:
class MyFragment : Fragment() {
private val myLayoutManager by lazy { LinearLayoutManager(context) }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recyclerView.layoutManager = myLayoutManager
}
override fun onDestroyView() {
recyclerView.layoutManager = null
super.onDestroyView()
}
}
The second option will work, because the condition for throwing an exception will be false. Here is the code from the method setLayoutManager of RecyclerView:
...
if (layout != null) {
if (layout.mRecyclerView != null) { // will be false
throw new IllegalArgumentException("LayoutManager " + layout
+ " is already attached to a RecyclerView:"
+ layout.mRecyclerView.exceptionLabel());
}
mLayout.setRecyclerView(this);
if (mIsAttached) {
mLayout.dispatchAttachedToWindow(this);
}
}

Categories

Resources