我已经看过很多这些问题,但我没有任何子元素,所以我不知道为什么这不正常。我将其移动到活动的片段中,它不再有效。我之前看到的问题与来自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)
答案 0 :(得分:0)
考虑移动此行
mRecyclerView.setHasFixedSize(true);
在将布局管理器分配给回收站视图的行之后。在调用setHasFixedSize
之前,您可能需要声明布局管理器答案 1 :(得分:0)
尝试在另一个方法覆盖中添加您的recyclerview管理器,Butterknife和对象可能正在进行工作,当您添加布局管理器时,例如onResume,或者数据需要加载时会发生什么。
答案 2 :(得分:0)
我对TodoItemView
(link)课程要达到的目标感到困惑。在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);
}
}
答案 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并且摆脱了异常。我不确定为什么会这样,但它解决了我的问题。