2016-09-25 58 views
0

我见过很多这些问题,但我没有任何子元素,所以我不知道为什么这不能正常工作。我把它从一个活动中移到了一个片段,它不再工作。我看到以前的问题与从回收站查看子元素有关,但这不是这种情况。这里是我的代码: 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

当然,这里是:http://pastebin.com/qC40tieM – user3496380

+0

如果你需要模型对象:http://pastebin.com/5GQiwuqf – user3496380

回答

0

考虑将这一行

mRecyclerView.setHasFixedSize(true); 

在您指定的布局管理器回收站视图中的行之后。您可能需要布局管理器声明,然后才能调用setHasFixedSize

+0

试过了,似乎没有工作。我不认为它很重要,但因为inflater.inflate方法调用发生异常。 – user3496380

0

尝试在另一个方法重载中添加您的recyclerview管理器,Butterknife和对象可能正在进行工作,当您将布局管理器添加到onResume时,或者当数据需要加载时。

+0

没有帮助,inflater.inflate方法调用发生异常;在我调用任何recyclerview/layoutmanager对象之前,会发生异常。 – user3496380

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

+0

嗨,感谢您编写这个工作示例。 TodoItemView的整个想法是提供一个自定义视图,我可以将其包含在我的应用程序中的其他片段/布局中。有没有办法将它包含在一个片段的回收站中(记住,当我只有一个活动时,这些都与TodoItemView一起工作)? – user3496380

+0

如果是这样的话,你也可以创建一个构造函数TodoListAdapter(int layoutResource),并像这样传递布局的引用mTodoListAdapter = new TodoListAdapter(R.layout.yourlayout)。如果您在整个应用程序中使用相同的适配器。 –

+0

找出问题的根本原因,我在我的活动的XML文件中包含了todo_recycler_view布局。我改变了这只是一个空的FrameLayout,并用我的片段中的todo_recycler_view替换了FrameLayout。使用TodoItemView在适配器中仍能正常工作 – user3496380

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" /> 

而是包括@在活动的布局文件布局/ todo_list_recycler_view的,我实例化我的片段时,刚刚替换todo_list_recycler_view空的FrameLayout和获取摆脱例外。我不确定为什么会出现这种情况,但它解决了我的问题。