2016-09-25 101 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和獲取擺脫例外。我不確定爲什麼會出現這種情況,但它解決了我的問題。