RecyclerView没有布局管理器

时间:2016-09-25 23:25:09

标签: java android android-recyclerview

我已经看过很多这些问题,但我没有任何子元素,所以我不知道为什么这不正常。我将其移动到活动的片段中,它不再有效。我之前看到的问题与来自recyclerview的子元素有关,但事实并非如此。这是我的代码:

public class TodoListFragment extends Fragment {

    @BindView(R.id.todo_recycler_view)
    protected RecyclerView mRecyclerView;

    @BindView(R.id.fab)
    protected FloatingActionButton mFab;

    private TodoListAdapter mTodoListAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    public static TodoListFragment newInstance() {
        return new TodoListFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.todo_list_recycler_view, container, false);

        ButterKnife.bind(this, view);
        mRecyclerView.setHasFixedSize(true);

        mLayoutManager = new LinearLayoutManager(getActivity());
        mRecyclerView.setLayoutManager(mLayoutManager);

        mTodoListAdapter = new TodoListAdapter();
        mRecyclerView.setAdapter(mTodoListAdapter);


        return view;
    }

    @OnClick(R.id.fab)
    public void onAdd() {
        TodoItemView todoItemView = new TodoItemView(getContext());
        todoItemView.setText("Schedule a dentist's appointment");
        todoItemView.setTime(new Date());
        mTodoListAdapter.addItem(todoItemView);
    }
}

这是todo_list_recycler_view.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/todo_recycler_view"
                                        android:scrollbars="vertical"
                                        android:layout_width="match_parent"
                                        android:layout_height="match_parent"
                                        app:layout_behavior="@string/appbar_scrolling_view_behavior"
                                        tools:context=".presentation.TodoActivity"
                                        tools:showIn="@layout/activity_todo_list" />

知道我为什么会收到此错误?

Caused by: java.lang.IllegalStateException: RecyclerView has no LayoutManager
                                                                                    at android.support.v7.widget.RecyclerView.generateLayoutParams(RecyclerView.java:3393)
                                                                                    at android.view.LayoutInflater.inflate(LayoutInflater.java:502)
                                                                                    at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
                                                                                    at com.vorple.shortlist.shortlist.presentation.TodoListFragment.onCreateView(TodoListFragment.java:44)

4 个答案:

答案 0 :(得分:0)

考虑移动此行

mRecyclerView.setHasFixedSize(true);

在将布局管理器分配给回收站视图的行之后。在调用setHasFixedSize

之前,您可能需要声明布局管理器

答案 1 :(得分:0)

尝试在另一个方法覆盖中添加您的recyclerview管理器,Butterknife和对象可能正在进行工作,当您添加布局管理器时,例如onResume,或者数据需要加载时会发生什么。

答案 2 :(得分:0)

我对TodoItemViewlink)课程要达到的目标感到困惑。在init()方法内部,您正在膨胀另一个视图,我假设您要使用此类来显示列表中的项目。这个问题出现在这个类中,根据你的逻辑,每次添加一个模型时,你都会重新膨胀视图。它应该被充气一次,然后存储参考,并在添加另一个项目时简单地抓回视图。在这种情况下,我不认为recyclerView能够回收您的视图。

所以,我重新创建了一个场景并简化了代码。但我不确定这是否是您问题的确切解决方案。但是,也许你可以在这里找到有用的东西。

1)活动

public class MainActivity extends AppCompatActivity{

private Button playBtn, startActivityBtn;
private MediaPlayer mediaPlayer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    getSupportFragmentManager().beginTransaction()
            .add(R.id.mainContent, new TododFragment())
            .commit();

}
}

2)片段

public class TododFragment extends Fragment {

private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private TodoListAdapter mTodoListAdapter;

public TododFragment() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_todod, container, false);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    mRecyclerView = (RecyclerView)view.findViewById(R.id.todo_recycler_view);
    mRecyclerView.setHasFixedSize(true);

    mLayoutManager = new LinearLayoutManager(getActivity());
    mRecyclerView.setLayoutManager(mLayoutManager);

    mTodoListAdapter = new TodoListAdapter();
    mRecyclerView.setAdapter(mTodoListAdapter);

    //Create 10 dummies data
    SimpleDateFormat dt = new SimpleDateFormat("h:mm a");
    for(int i = 0; i < 10; i++){
        if(i % 2 == 0)
            mTodoListAdapter.addItem(new TodoItem("Schedule a dentist's appointment", dt.format(new Date()), 0));
        else
            mTodoListAdapter.addItem(new TodoItem("Schedule a dentist's appointment", dt.format(new Date()), 1));
    }
}
}

3)模型

public class TodoItem {
private String text;
private String time;
//LayoutType is used to display different layout.
private int layoutType;

public TodoItem(String text, String time, int layoutType) {
    this.text = text;
    this.time = time;
    this.layoutType = layoutType;
}

public String getText() {
    return text;
}

public void setText(String text) {
    this.text = text;
}

public String getTime() {
    return time;
}

public void setTime(String time) {
    this.time = time;
}

public int getLayoutType() {
    return layoutType;
}

public void setLayoutType(int layoutType) {
    this.layoutType = layoutType;
}
}

4)适配器(在这种情况下,我有两个布局。如果你想使用一个布局,请删除getItemViewType

public class TodoListAdapter extends RecyclerView.Adapter<TodoListAdapter.TodoItemViewHolder> {
private List<TodoItem> mItems;


public static class TodoItemViewHolder extends RecyclerView.ViewHolder{

    public TextView mTextViewText;
    public TextView mTextViewTime;

    public TodoItemViewHolder(View itemView) {
        super(itemView);

        mTextViewText = (TextView)itemView.findViewById(R.id.mTextViewText);
        mTextViewTime = (TextView)itemView.findViewById(R.id.mTextViewTime);
    }
}

public TodoListAdapter() {
    mItems = new ArrayList<>();
}

@Override
public int getItemViewType(int position) {
    //ItemViewType will return an int for every row. You can use this to control with layout you want to display
    return mItems.get(position).getLayoutType();
}

@Override
public TodoItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    //get the viewType and display the layout accordingly
    View view = null;
    if(viewType == 0){
        view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.todo_list_item, parent, false);
    }
    else{
        view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.todo_list_item2, parent, false);
    }

    TodoItemViewHolder rcv = new TodoItemViewHolder(view);
    return rcv;
}

@Override
public void onBindViewHolder(TodoItemViewHolder holder, int position) {
    holder.mTextViewText.setText(mItems.get(position).getText());
    holder.mTextViewTime.setText(mItems.get(position).getTime());
}

@Override
public int getItemCount() {
    return mItems.size();
}

public void addItem(TodoItem item) {
    mItems.add(item);
    notifyItemInserted(mItems.size() - 1);
}
}

6)结果 enter image description here

答案 3 :(得分:0)

我找出了异常的原因。

以下是我在活动的XML文件中更改的内容:

<!-- <include layout="@layout/todo_list_recycler_view" /> -->
    <FrameLayout
        android:id="@+id/todo_list_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

而不是在活动的布局文件中包含@ layout / todo_list_recycler_view,我只是在实例化我的片段时用todo_list_recycler_view替换了空的FrameLayout并且摆脱了异常。我不确定为什么会这样,但它解决了我的问题。