android.support.v7.widget.RecyclerView.onMeasure 处的 java.lang.NullPointerException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26737113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.lang.NullPointerException at android.support.v7.widget.RecyclerView.onMeasure
提问by Randy
I try to use RecyclerView with RecyclerView.Adapter but here is something wrong. I post my code below:
我尝试将 RecyclerView 与 RecyclerView.Adapter 一起使用,但这里出了点问题。我在下面发布我的代码:
Layout:
布局:
<android.support.v7.widget.RecyclerView
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/topic_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />
topic_tile.xml:
topic_tile.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/tile_height">
<com.makeramen.RoundedImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/avatar"
android:padding="16dp"
app:riv_corner_radius="72dp"
android:layout_height="72dp"
android:layout_width="72dp"
/>
<LinearLayout
android:id="@+id/text_layout"
android:orientation="vertical"
android:paddingTop="@dimen/text_padding_top_and_bottom"
android:paddingBottom="@dimen/text_padding_top_and_bottom"
android:paddingRight="16dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/title"
android:textSize="@dimen/primary_font"
android:paddingLeft="@dimen/text_padding_left"
android:textColor="#000000"
android:text="Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/author"
android:textSize="@dimen/secondary_font"
android:paddingLeft="@dimen/text_padding_left"
android:text="author"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</RelativeLayout>
Here is in onCreate()
这是在 onCreate()
public class TitleListActivity extends ActionBarActivity {
private RecyclerView topic_view;
private RecyclerView.LayoutManager mLayoutManager;
private TitlelistAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_title_list);
.....
topic_view = (RecyclerView)findViewById(R.id.topic_view);
adapter = new TitlelistAdapter(topicList);
topic_view.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(TitleListActivity.this);
topic_view.setLayoutManager(mLayoutManager);
topic_view.setItemAnimator(new DefaultItemAnimator());
topic_view.setAdapter(adapter);
the Adapter:
适配器:
public class TitlelistAdapter extends RecyclerView.Adapter<TitlelistAdapter.ViewHolder> {
public List<Topic> topicList;
public static class ViewHolder extends RecyclerView.ViewHolder{
TextView title;
TextView author;
RoundedImageView avatar;
public ViewHolder(View itemView) {
super(itemView);
title = (TextView)itemView.findViewById(R.id.title);
author = (TextView)itemView.findViewById(R.id.author);
avatar = (RoundedImageView)itemView.findViewById(R.id.avatar);
}
}
public TitlelistAdapter(List<Topic> topicList){
this.topicList = topicList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.topic_tile,viewGroup,false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
viewHolder.title.setText(topicList.get(i).title);
viewHolder.author.setText(topicList.get(i).member.username);
}
@Override
public long getItemId(int position) {
return super.getItemId(position);
}
@Override
public int getItemCount() {
return topicList.size();
}
}
Here is the exception:
这是例外:
java.lang.NullPointerException
at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:1694)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.support.v7.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:453)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:16497)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2291)
at android.view.View.measure(View.java:16497)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1912)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1109)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1291)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:996)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5600)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
at android.view.Choreographer.doCallbacks(Choreographer.java:574)
at android.view.Choreographer.doFrame(Choreographer.java:544)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Is it something I didn't init or something I should write more?
是我没有初始化的东西还是我应该写更多的东西?
回答by Android2390
Your xml shows that you have two android namespaces which actually should give you an error because in android you are allowed to use the namespace only once. Remove the linearLayout from your main layout as it seems unnecessary. Check your custom Row layout i.e topic_tile
as well for any similar errors
您的 xml 显示您有两个 android 命名空间,这实际上应该给您一个错误,因为在 android 中,您只能使用该命名空间一次。从您的主布局中删除 linearLayout,因为它似乎没有必要。检查您的自定义行布局,即topic_tile
是否有任何类似的错误
<android.support.v7.widget.RecyclerView
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/topic_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />
EDIT :
编辑 :
in onCreate()
在 onCreate()
private RecyclerView.LayoutManager mLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
.
.
.
mLayoutManager = new LinearLayoutManager(this);
recycleView.setLayoutManager(mLayoutManager);
}
回答by MewX
If your are facing the same issue for RecycleView inside a fragment, try to use this code.
如果您在片段中遇到 RecycleView 的相同问题,请尝试使用此代码。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_latest, container, false);
// get recycler view
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.novel_item_list);
//mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
String[] abc = {"hi","how are you","this is recycler"};
// specify an adapter (see also next example)
mAdapter = new RecyclerViewAdapter(abc);
mRecyclerView.setAdapter(mAdapter);
return rootView;
}
回答by Son Nguyen Thanh
You have to set LayoutManager
for RecycleView
:
您必须设置LayoutManager
为RecycleView
:
Currently, android supports 3 kinds of layouts.
目前,android 支持 3 种布局。
If you want it seems a normal ListView
, use LinearLayoutManager
.
如果您希望它看起来很正常ListView
,请使用LinearLayoutManager
.
If you want it seems a gridView, use GridLayoutManager
.
如果您希望它看起来像一个 gridView,请使用GridLayoutManager
.
If you want it seem staggered, use StaggeredGridLayoutManager
如果您希望它看起来交错,请使用 StaggeredGridLayoutManager
Constructors for 3 kinds layouts above
上面 3 种布局的构造函数
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2);
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(spanCount, StaggeredGridLayoutManager.HORIZONTAL);
Then you set LinearLayout
to RecycleView
( in this case I used LinearLayoutManager
然后你设置LinearLayout
为RecycleView
(在这种情况下我使用LinearLayoutManager
recyclerView = (RecyclerView) view.findViewById(R.id.saved_recycle_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(linearLayoutManager);
Anyway, use OttoBusLibrary to pass out events from the Adapter to Activity/Fragment containing the RecycleView
.
Good luck !
无论如何,使用OttoBus库将事件从适配器传递到包含RecycleView
. 祝你好运 !
回答by Dan Goldstein
I got this error when my RecyclerView had no LayoutManager. Adding this code fixed the problem:
当我的 RecyclerView 没有 LayoutManager 时,我收到此错误。添加此代码解决了问题:
recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
回答by Hassan Gilak
For anyone trying to use a ViewPager for tabs, and inside their tabs have a RecyclerView which causes this crazy error, I suggest to postpone inflating by creating yet another Fragment for including only the RecylerView.
对于任何试图将 ViewPager 用于选项卡的人,并且在他们的选项卡内有一个 RecyclerView 会导致这个疯狂的错误,我建议通过创建另一个仅包含 RecylerView 的 Fragment 来推迟膨胀。
This xml file is one of my tabs which contain a frame layout instead a recycler .
这个 xml 文件是我的选项卡之一,它包含一个框架布局而不是一个 recycler 。
shop_most_views_fragment.xml
shop_most_views_fragment.xml
<?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">
<FrameLayout
android:id="@+id/most_view_item_frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f3f3f3" />
</LinearLayout>
its java class
它的java类
public class MostViews extends Fragment {
private String title;
private int page;
View convertedView;
RecyclerView grids;
public static MostViews newInstance(int page, String title) {
MostViews fragmentFirst = new MostViews();
Bundle args = new Bundle();
args.putInt("someInt", page);
args.putString("someTitle", title);
fragmentFirst.setArguments(args);
return fragmentFirst;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
page = getArguments().getInt("someInt", 0);
title = getArguments().getString("someTitle");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
convertedView = inflater.inflate(R.layout.shop_most_views_fragment, container, false);
transitMasonaryLayoutFragmentIntoFramLayout();
return convertedView;
}
private void transitMasonaryLayoutFragmentIntoFramLayout() {
MasanoryLayout masanoryLayout = new MasanoryLayout();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.most_view_item_frameLayout, masanoryLayout).commit();
}
}
so we have a frame layout to put our recylcer fragment into it.
所以我们有一个框架布局来将我们的回收器片段放入其中。
shop_most_view_masanory_fragment.xml
shop_most_view_masanory_fragment.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">
<android.support.v7.widget.RecyclerView
android:id="@+id/mostViewsItem"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
its java class
它的java类
public class MasanoryLayout extends Fragment {
View convertedView;
RecyclerView grids;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
convertedView = inflater.inflate(R.layout.shop_most_view_masanory_fragment, container, false);
grids = (RecyclerView) convertedView.findViewById(R.id.mostViewsItem);
setLayoutManagerOnRecyclerView();
MasonryAdapter adapter = new MasonryAdapter(initializeData());
grids.setAdapter(adapter);
return convertedView;
}
private void setLayoutManagerOnRecyclerView() {
grids.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL));
}
private List<StoreItem> initializeData() {
List<StoreItem> storeItems = new ArrayList<>();
storeItems.add(new StoreItem("?????", "?????", R.drawable.detailed_index_store));
storeItems.add(new StoreItem("?????", "?????", R.drawable.clothstore));
storeItems.add(new StoreItem("?????", "?????", R.drawable.detailed_index_store));
storeItems.add(new StoreItem("?????", "?????", R.drawable.clothstore));
storeItems.add(new StoreItem("?????", "?????", R.drawable.detailed_index_store));
storeItems.add(new StoreItem("?????", "?????", R.drawable.detailed_index_store));
storeItems.add(new StoreItem("?????", "?????", R.drawable.clothstore));
return storeItems;
}
}
as you see your FragmentPagerAdapter would call MostViews to be inflated and MostViews itself would call MasanoryLayout to be inflated. so we escaped FragmentPagerAdapter context ;)
如您所见,您的 FragmentPagerAdapter 会调用 MostViews 进行膨胀,而 MostViews 本身会调用 MasanoryLayout 进行膨胀。所以我们转义了 FragmentPagerAdapter 上下文 ;)