2016-09-25 5 views
0

Ich habe viele dieser Fragen gesehen, aber ich habe keine Kind-Elemente, so dass ich nicht weiß, warum das nicht richtig funktioniert. Ich habe dies in ein Fragment einer Aktivität verschoben und es funktioniert nicht mehr. Ich habe gesehen, dass vorherige Fragen Probleme mit Kindelementen aus der Recycleransicht haben, aber das ist hier nicht der Fall. Hier ist mein Code: RecyclerView hat keinen Layout-Manager

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); 
    } 
} 

Und hier ist die 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" /> 

Jede Idee, warum ich diesen Fehler bin immer?

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

Können Sie Ihren Adapter wenn möglich hinzufügen? Ich muss in meinem PC laufen. –

+0

Sicher, hier ist es hier: http://pastebin.com/qC40tieM – user3496380

+0

Und falls Sie das Modellobjekt benötigen: http://pastebin.com/5GQiwuqf – user3496380

Antwort

0

Betrachten Sie diese Linie

mRecyclerView.setHasFixedSize(true); 

nach der Linie bewegt, wo Sie die Layout-Manager zu dem Recycler Ansicht zuweisen. Sie müssen möglicherweise den Layout-Manager deklariert, bevor Sie setHasFixedSize aufrufen können

+0

Versuchte es, schien nicht zu funktionieren. Ich denke nicht, dass es trotzdem wichtig ist, da die Ausnahme bei der Methode inflater.inflate auftritt. – user3496380

0

versuchen Sie hinzufügen Ihre Recyclerview-Manager in einer anderen Methode überschreiben, kann es Arbeit mit Butterknife und das Objekt, was passiert, wenn Sie den Layout-Manager in, sagen onResume hinzufügen oder wenn die Daten geladen werden müssen.

+0

Es hilft nicht, die Ausnahme tritt beim Aufruf der Methode inlater.inflate auf; Die Exception wird getroffen, bevor ich eines der recycleview/layoutmanager-Objekte aufruft. – user3496380

0

Ich bin sehr verwirrt mit was Sie mit TodoItemView (link) Klasse erreichen wollen. In der Methode init() werden Sie eine andere Ansicht aufblasen, von der ich annahm, dass Sie diese Klasse verwenden möchten, um das Objekt in der Liste anzuzeigen. Das Problem tritt innerhalb dieser Klasse auf, die, basierend auf Ihrer Logik, jedes Mal, wenn Sie ein Modell hinzufügen, die Ansicht wieder aufblasen. Es sollte einmal aufgeblasen werden, dann speichern Sie die Referenz und greifen Sie einfach die Ansicht zurück, wenn Sie ein anderes Element hinzufügen. In diesem Fall glaube ich nicht, dass RecyclerView Ihre Ansicht recyceln kann.

Also, ich habe ein Szenario neu erstellt und Ihren Code vereinfacht. Aber ich bin mir nicht sicher, ob dies die genaue Lösung Ihres Problems ist. Aber vielleicht finden Sie hier etwas Nützliches.

1) Tätigkeit

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) Fragment

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) Modell

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) Adapter (In diesem Fall habe ich zwei Layout. Wenn Sie möchten, Um ein Layout zu verwenden, entfernen Sie)

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) Ergebnis enter image description here

+0

Hey vielen Dank für das Schreiben dieses Arbeitsbeispiels. Die ganze Idee von TodoItemView besteht jedoch darin, eine benutzerdefinierte Ansicht bereitzustellen, die ich in anderen Fragmenten/Layouts in meiner App einfügen kann. Gibt es keine Möglichkeit, dies innerhalb einer Recyclerview innerhalb eines Fragments zu berücksichtigen (bedenken Sie, dass dies alles mit TodoItemView funktionierte, als ich nur eine Aktivität hatte)? – user3496380

+0

Wenn das der Fall ist, können Sie auch einen Konstruktor TodoListAdapter (int layoutResource) erstellen und übergeben Sie die Referenz des Layouts wie diese mTodoListAdapter = new TodoListAdapter (R.layout.yourlayout). Wenn Sie in Ihrer App den gleichen Adapter verwenden. –

+0

Ich habe die Ursache des Problems herausgefunden. Ich habe das todo_recycler_view-Layout in die XML-Datei meiner Aktivität aufgenommen. Ich änderte das, um ein leeres FrameLayout zu sein, und ersetzte dieses FrameLayout durch todo_recycler_view in meinem Fragment. Die Verwendung von TodoItemView funktioniert im Adapter weiterhin einwandfrei – user3496380

0

ich die Ursache der Ausnahme herausgefunden. Hier

ist, was ich in meiner Tätigkeit der XML-Datei geändert:

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

Statt einschließlich @ Layout/todo_list_recycler_view in der Layout-Datei Aktivität, ich habe gerade die leere FrameLayout mit todo_list_recycler_view ersetzt, wenn mein Fragment Instanziieren und bekommt los von der Ausnahme. Ich bin nicht sicher, warum das der Fall ist, aber es löst das Problem für mich.

Verwandte Themen