2016-07-20 3 views
2
  • 私は自分のアプリでRecyclerviewを実装しています。アイテムをクリックして別のリストビューを更新する必要があります。そのため、アクティビティでonClickイベントを実装しました。それはうまく動作します。
  • しかし、私はハイライトRecyclerViewの選択ビューを必要とし、その他は正常なままです。
  • 私は、RecyclerView getChildメソッドを使用して、すべてのビューを通常にしてからハイライトを選択しました。
  • 私はRecyclerViewのVisibleビューでのみ動作することを認識しています。 しかし、私はRecyclerviewのすべてのビューを正常にする必要がありました。そして、より大きな位置でgetChildAtを使用した場合、合計可視回数はNULLポインタ例外を返します。 29

    RecyclerView getChildAt(position)はnullを返します

    E /商品のRv:15

    E /子アダプタ:30

    私はE /商品順位

を得ること

  • ログイン

    MainActivity.java

    public class MainActivity extends Activity { 
    RecyclerView reView; 
    ArrayList<RvModel> rvModels; 
    revAdapter adapter; 
    
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
        reView = (RecyclerView) findViewById(R.id.reView); 
        reView.setLayoutManager(new GridLayoutManager(MainActivity.this, 3)); 
    
        rvModels = new ArrayList<>(); 
        adapter = new revAdapter(MainActivity.this, rvModels); 
        reView.setAdapter(adapter); 
        prepareData(); 
        reView.addOnItemTouchListener(new RecyclerItemClickListener(MainActivity.this, reView, new RecyclerItemClickListener.OnItemClickListener() { 
         @Override 
         public void onItemClick(View view, int position) { 
          Log.e("Item Pos", "" + position); 
          Log.e("Item Rv", "" + reView.getChildCount()); 
          Log.e("Child Adapter", "" + reView.getAdapter().getItemCount()); 
    
          for (int i = 0; i < reView.getChildCount(); i++) { 
           View v = reView.getChildAt(i); 
           TextView txtText = (TextView) v.findViewById(R.id.txtText); 
    
           txtText.setBackgroundColor(Color.WHITE); 
           txtText.setTextColor(Color.BLUE); 
          } 
          TextView txtText = (TextView) view.findViewById(R.id.txtText); 
          txtText.setBackgroundColor(Color.BLUE); 
          txtText.setTextColor(Color.WHITE); 
         } 
    
         @Override 
         public void onLongItemClick(View view, int position) { 
    
         } 
        })); 
    } 
    
    private void prepareData() { 
        rvModels.clear(); 
        for (int i = 0; i < 30; i++) { 
         RvModel rvModel = new RvModel(); 
         rvModel.setTitle("Item : " + i); 
         rvModels.add(rvModel); 
        } 
        adapter.notifyDataSetChanged(); 
        } 
    } 
    

    revAdapter.java

    public class revAdapter extends RecyclerView.Adapter<revAdapter.ViewHolder> { 
    Context context; 
    ArrayList<RvModel> rvModels; 
    LayoutInflater inflater; 
    
    public revAdapter(Context context, ArrayList<RvModel> rvModels) { 
        this.context = context; 
        this.rvModels = rvModels; 
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 
    
    public class ViewHolder extends RecyclerView.ViewHolder { 
        ImageView ivIcon; 
        TextView txtText; 
    
        public ViewHolder(View itemView) { 
         super(itemView); 
         ivIcon = (ImageView) itemView.findViewById(R.id.ivIcon); 
         txtText = (TextView) itemView.findViewById(R.id.txtText); 
        } 
    } 
    
    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
        View itemView = inflater.inflate(R.layout.rv_raw, parent, false); 
        return new ViewHolder(itemView); 
    } 
    
    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
        RvModel rvModel = rvModels.get(position); 
        holder.txtText.setText(rvModel.getTitle()); 
    } 
    
    @Override 
    public int getItemCount() { 
        return rvModels.size(); 
    } 
    
    @Override 
    public int getItemViewType(int position) { 
        return position; 
        } 
    } 
    

    rv_raw.xml

    <?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:gravity="center" 
    android:orientation="vertical"> 
    
    <LinearLayout 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:orientation="vertical" 
        android:padding="10dp"> 
    
        <ImageView 
         android:id="@+id/ivIcon" 
         android:layout_width="100dp" 
         android:layout_height="100dp" 
         android:src="@mipmap/ic_launcher" /> 
    
        <TextView 
         android:id="@+id/txtText" 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:text="Medium Text" 
         android:textAppearance="?android:attr/textAppearanceMedium" /> 
    </LinearLayout> 
    

答えて

4

問題は、リストビューのようなrecyclerViewは、子ビュー(項目)の数が依存しているということですあなたの画面サイズではなく、どれくらいのアイテムを持っていますか。それはOOMの例外からアプリケーションを防止します。たとえば、1M個のアイテムがある場合、ロジックから、リサイクラビューには1M個のサブビューが作成されなければならず、それは悪いことです。リストビューの詳細については、hereを参照してください(リサイクラービューも同じように動作します)

したがって、onClickイベントでは、表示を見つけて変更する必要はありません。あなたはいくつかのいわゆる "設定"を変更し、より多くの最適化のためにnotifyDataSetChangedまたはnotifyItemChangedと書く必要があります。

また、あなたのコードを確認しました。私はあなたに懇願しています。そのため、あなたのリサイクルビュー内のビューの一種類のみであり、あなたはすべての項目に同じホルダーを使用している

@Override 
public int getItemViewType(int position) { 
    return position; 
} 

:、、このオーバーライドされた機能を削除してくださいしてください。この方法をオーバーライドすることで、リサイクル業者の視点から、すべてのアイテムが異なるレイアウトを使用してパフォーマンスが低下することを伝えます。アダプターで

reView.addOnItemTouchListener(new RecyclerItemClickListener(MainActivity.this, reView, new RecyclerItemClickListener.OnItemClickListener() { 
    @Override 
    public void onItemClick(View view, int position) { 
     Log.e("Item Pos", "" + position); 
     Log.e("Item Rv", "" + reView.getChildCount()); 
     Log.e("Child Adapter", "" + reView.getAdapter().getItemCount()); 

     if (!adapter.isChecked(position)) { 
      adapter.setChecked(position); 
     } 
    } 

    @Override 
    public void onLongItemClick(View view, int position) { 

    } 
})); 

private int checkedPosition = -1; 

@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 
    RvModel rvModel = rvModels.get(position); 
    holder.txtText.setText(rvModel.getTitle()); 

    if (position == checkedPosition) { 
     txtText.setBackgroundColor(Color.BLUE); 
     txtText.setTextColor(Color.WHITE); 
    } else { 
     txtText.setBackgroundColor(Color.WHITE); 
     txtText.setTextColor(Color.BLUE); 
    } 
} 

public boolean isChecked(int position) { 
    return checkedPosition == position; 
} 

public void setChecked(int position) { 
    int prevChecked = checkedPosition; 
    checkedPosition = position; 

    if (prevChecked != -1) { 
     notifyItemChanged(prevChecked); 
    } 
    notifyItemChanged(checkedPosition) 
} 
+0

おかげで偉大な説明

だから、あなたの質問に応じて、あなたはいくつかの並べ替えを持っています。また、getItemViewTypeメソッドを使用したくないときは、この例ではなく、スクロール中にRecyclerビューのビューを使用していないときはいつでも更新します。そのリサイクルビューのグリッドレイアウトを使用する別のアプリ内で発生します。 –

関連する問題