2017-01-08 2 views
0

私はRecyclerViewのリストを持っています。このリストは、デフォルトのレイアウトとCardViewのレイアウトの2つのレイアウトの中から選択します。ユーザーがまだCardViewを作成していない場合、デフォルトのUIレイアウトが最初に表示されます。ユーザーがCardViewを作成して保存した後、レイアウトはCardViewレイアウトに切り替わります。レイアウトは、私はこれらの2つの方法使用した場合のレイアウトの切り替えが正常に動作しAndroidはなぜRecyclerView Adapter crashingですか?

0と1の間の切り替え、「ビュータイプ」を使用して切り替え:

public int getItemCount() { 
    return contactList.size()>0 ? contactList.size():1; 
} 

public int getItemViewType(int position) { 
    return contactList.size() == 0 ? 0:1; 
} 

をそれから私は別の使用のための以下の方法を添加しアプリがクラッシュしています:

public Contact getItem(int position) { 
    return contactList.get(position); 
} 

私はここで何が欠けていますか?

Logcat:

致命的な例外:メイン java.lang.RuntimeException: ジャワ:活性 ComponentInfo {com.example.jdw.v52/com.wimso.v052.MainActivity}を開始できません。 lang.IndexOutOfBoundsException:無効なインデックス0は、サイズがで android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)で android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059) で0であるとroid.app.ActivityThread.access $ 600(ActivityThread.java:130) ( )android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1195) (android.os.Handler.dispatchMessage(Handler.java:99) android.os.Looper.loop(Looper.java:137)の android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(ネイティブメソッド) at java .lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit。 main(ZygoteInit。ジャワ:553) によって引き起こさdalvik.system.NativeStart.main(ネイティブメソッド) で:java.lang.IndexOutOfBoundsException:無効なインデックス0、サイズ はjava.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.javaで0 あります。 java.util.ArrayList.get(ArrayList.java:304) における251) でcom.wimso.v052.adapter.ContactListAdapter.getItem(ContactListAdapter.java:95) com.wimso.v052.adapterで 。 ContactListAdapter.clear(ContactListAdapter.java:72) at com.wimso.v052.MainActivity.loadData(MainActivity.java:171) com.wimso.v052.MainActivity.onStart(MainActivity。Javaの:126)

Adapter.java 
... 
public ContactListAdapter(Context context) { 
    this.context = context; 
    this.contactList = new ArrayList<>(); 
    mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

public void add(Contact item) { 
    if (contactList.size()==0) { 
     // if list is empty 
     // remove empty cards first 
     contactList.clear(); 
     notifyDataSetChanged(); 
    } 
    contactList.add(item); 
    notifyItemInserted(contactList.size() -1); 
} 

public void clear() { 
    while (getItemCount() > 0) { 
     remove(getItem(0)); 
    } 
} 

// Remove an item from the RecyclerView/ 
public void remove(Contact item) { 
    if (contactList.size()==0) { 
     // if no more contacts in list, 
     // we rebuild from scratch 
     contactList.clear(); 
     notifyDataSetChanged(); 
    } 
    int position = contactList.indexOf(item); 
    if (position > -1) { 
     contactList.remove(position); 
     notifyItemRemoved(position); 
     notifyItemRangeChanged(position, contactList.size()); // I added this. 
    } 
} 

// Get the Item's position. 
public Contact getItem(int position) { 
    return contactList.get(position); 
} 

// Update the existing List of RecyclerView items. 
public void addAll(List<Contact> contactList) { 
    for (Contact contact : contactList) { 
     add(contact); 
    } 
} 

@Override 
public int getItemCount() { 
    return contactList.size()>0 ? contactList.size():1; 
} 

// if there are zero CardViews, use viewType 0 to get default_layout, 
// otherwise provide a viewType of 1 to for each CardView in order to 
// show the singlecard_layout. 
@Override 
public int getItemViewType(int position) { 
    return contactList.size() == 0 ? 0:1; 
} 

// Get the Item's Id. 
public long getItemId(int position) { 
    return contactList.get(position).getId(); 
} 

private static class DefaultViewHolder extends RecyclerView.ViewHolder { 
    DefaultViewHolder(View itemView) { 
     super(itemView); 
    } 
} 

private class ContactViewHolder extends RecyclerView.ViewHolder { 

    CountDownTimer timer; 
    ... 
    private ContactViewHolder(View itemView) { 
     super(itemView); 

    ... 
    @Override 
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 

    if (viewType == 0) { 
     View itemView = mLayoutInflater.inflate(R.layout.defaultcard_layout, parent, false); 
     return new DefaultViewHolder(itemView); 
    } else { 
     View itemView = mLayoutInflater.inflate(R.layout.list_contact_item, parent, false); 
... 
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) { 
    int type = getItemViewType(position); 
    if (type == 1) { 
     Contact contact = contactList.get(position); 
     final ContactViewHolder holder = (ContactViewHolder) viewHolder; 
    ... 

答えて

1

は、ここで問題です:

public int getItemCount() { 
    return contactList.size()>0 ? contactList.size():1; 
} 

contactListのサイズが0の場合、あなたはまだ、少なくとも1つのビューを持っているRecyclerViewを戻ってきています。その1つのビューがすでに0ので、これであなたのcontactListにアクセスしようとする:あなたはこれを行うことができ

java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0 

:場合

public int getItemCount() { 
     return contactList.size() != null ? contactList.size() : 0; 
} 

あなたはヌルcontactListを取得します。

または

public int getItemCount() { 
    return contactList.size(); 
} 

あなたのアダプタへの入力は決してnullにcontactListあれば、単にリストのサイズがどうなる返します。

+0

私はちょうど "return contactList.size();"サイズが0(デフォルトレイアウトを表示するはずです)から1以上(CardViewレイアウトを表示)になると、レイアウトは適切に切り替わりません。 – AJW

+0

このような目的でgetItemTypeを使用しないでください。これは、単一のrecyclerView内に複数のビュータイプを作成するために使用されます。別の方法を使用してください。 –

+0

2つのCardViewレイアウトをより適切に切り替える方法に関する推奨事項はありますか? – AJW

1

問題は、アダプタのgetItem()getItemId()が連絡先リストが空であることを正しくチェックしていないことです。そのリストが空であっても、アダプターは1のサイズを報告するので、RecyclerViewが表示する項目を持つことが予想されるため、これらのメソッドが呼び出されます。

アダプターにアイテムがない場合、別のビューを表示しようとしているようです。アダプターだけでこれを行うことは可能ですが、あなたのレイアウトに別のViewを置き、連絡先のリストをロードするたびに可視性を変更する方が簡単で洗練されたものになると思います。この方法では、アダプタはほとんど複雑である必要はありません。

adapter.setItems(list); // or add, whatever 
if (list.size() > 0) { 
    recyclerView.setVisiblity(View.VISIBLE); 
    emptyView.setVisiblity(View.GONE); 
} else { 
    emptyView.setVisiblity(View.VISIBLE); 
    recyclerView.setVisiblity(View.GONE); 
} 
0

私は、ホスティング活動のテーマに起因する同様のクラッシュがあります。

<item name="android:windowIsTranslucent">true</item>

私の活動の内部recyclerviewを持っているフラグメントと透明でした。すべてがロードされますが、回転すると同じエラーが発生します。フラグメントやリサイクルビューの実装に間違いはありませんでした。それはアクティビティのスタイルでした。削除によって問題が解決されます。

関連する問題