2016-10-03 7 views
-1

私は、このアダプタクラスを持っています。そこには、リストにオブジェクトがあります。recyclerloveアイテムの複数のビューをクリック可能にするにはどうすればいいですか?

public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> { 
private Context context; 
private Shop shop; 

public ProductAdapter(Context context, Shop shop) { 
    this.context = context; 
    this.shop = shop; 
} 

@Override 
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 
    View v = inflater.inflate(R.layout.product_row, parent, false); 
    return new ProductViewHolder(v); 
} 

@Override 
public void onBindViewHolder(ProductViewHolder holder, int position) { 
    holder.tvProductTitle.setText(shop.products.get(position).getTitle()); 
    holder.tvProductDescription.setText(shop.products.get(position).getDescription()); 
    Glide.with(context) 
      .load(shop.products.get(position).getImageUrl()) 
      .placeholder(android.R.drawable.ic_menu_upload_you_tube) 
      .error(android.R.drawable.stat_notify_error) 
      .diskCacheStrategy(DiskCacheStrategy.RESULT) 
      .into(holder.ivProduct); 
} 

@Override 
public int getItemCount() { 
    if (shop.products != null) { 
     return shop.products.size(); 
    } 
    return 0; 
} 

public static class ProductViewHolder extends RecyclerView.ViewHolder { 
    private TextView tvProductTitle, tvProductDescription; 
    private ImageView ivProduct; 

    public ProductViewHolder(View itemView) { 
     super(itemView); 
     tvProductTitle = (TextView) itemView.findViewById(R.id.tvProductTitle); 
     tvProductDescription = (TextView) itemView.findViewById(R.id.tvProductDescription); 
     ivProduct = (ImageView) itemView.findViewById(R.id.ivProduct); 
    } 
} 

public interface ClickListener { 
    void onClick(View v, int position); 

    void onLongClick(View v, int position); 
} 

public static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener { 
    private GestureDetector gestureDetector; 
    private ProductAdapter.ClickListener clickListener; 

    public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ProductAdapter.ClickListener clickListener) { 
     this.clickListener = clickListener; 
     gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { 
      @Override 
      public boolean onSingleTapUp(MotionEvent e) { 
       return true; 
      } 

      @Override 
      public void onLongPress(MotionEvent e) { 
       View child = recyclerView.findChildViewUnder(e.getX(), e.getY()); 
       if (child != null && clickListener != null) { 
        clickListener.onLongClick(child, recyclerView.getChildAdapterPosition(child)); 
       } 
      } 
     }); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { 
     View child = rv.findChildViewUnder(e.getX(), e.getY()); 
     if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) { 
      clickListener.onClick(child, rv.getChildAdapterPosition(child)); 
     } 
     return false; 
    } 

    @Override 
    public void onTouchEvent(RecyclerView rv, MotionEvent e) { 

    } 

    @Override 
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { 

    } 
} 

このアダプターは、私が選択した製品とそのパラメーターで別のアクティビティーを開くrecyclerviewから項目をクリックできる場所に使用します。アイテム全体をクリックするのではなく、その一部をクリックしたいと思います(イメージビューと言うことができます)。しかし、私はまた、異なる機能を持つrecyclerview項目自体にチェックボックスを入れたいと思います。現時点では、アダプタクラスでインテントを使用することはできません。今設定されている方法では、アイテム全体をクリックするだけです。上記のように私はどのように動作させることができますか?

public class ProductsFragment extends android.support.v4.app.Fragment { 
private RecyclerView rvProduct; 
private RecyclerView.LayoutManager layoutManager; 
private ProductAdapter productAdapter; 

public static ProductsFragment newInstance(Bundle args) { 
    ProductsFragment fragment = new ProductsFragment(); 
    fragment.setArguments(args); 
    return fragment; 
} 

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View v = inflater.inflate(R.layout.fragment_products, container, false); 
    rvProduct = (RecyclerView) v.findViewById(R.id.rvProduct); 
    rvProduct.setHasFixedSize(true); 
    layoutManager = new GridLayoutManager(getContext(), 2); 
    rvProduct.setLayoutManager(layoutManager); 
    Bundle bundle = getArguments(); 
    final Shop shop = (Shop) bundle.getSerializable("shop"); 
    productAdapter = new ProductAdapter(getContext(), shop); 
    rvProduct.setAdapter(productAdapter); 
    productAdapter.notifyDataSetChanged(); 

    rvProduct.addOnItemTouchListener(new ProductAdapter.RecyclerTouchListener(getContext(), rvProduct, new ProductAdapter.ClickListener() { 
     @Override 
     public void onClick(View v, int position) { 
      Intent details = new Intent(getContext(), ProductDetailsActivity.class); 
      details.putExtra("product", shop.products.get(position)); 
      startActivity(details); 
     } 

     @Override 
     public void onLongClick(View v, int position) { 

     } 
    })); 
    return v; 
} 
} 

編集:私はこれを行うことができた 、これは正しいと効率的な方法であれば教えてください:

holder.tvProductTitle.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent i = new Intent(context, ProductDetailsActivity.class); 
      i.putExtra("product", shop.products.get(position)); 
      context.startActivity(i); 
     } 
    }); 

答えて

1

あなたのやり方は正しくありません。 新しいListenerが設定されるたびに、リストをスクロールするときにonBindViewHolderが繰り返し呼び出されるため、

代わりに、アダプタのViewHolderクラスでリスナーを設定する必要があります。 getAdapterPosition()メソッドを使用して、クリックされた項目の位置を取得します。 例:

public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {  
private Context context; private Shop shop; 
public ProductAdapter(Context context, Shop shop) { 
this.context = context; 
this.shop = shop; 
} 
@Override public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 
View v = inflater.inflate(R.layout.product_row, parent, false); 
return new ProductViewHolder(v); 
} 
@Override public void onBindViewHolder(ProductViewHolder holder, int position) { 
holder.tvProductTitle.setText(shop.products.get(position).getTitle()); 
holder.tvProductDescription.setText(shop.products.get(position).getDescription()); 
Glide.with(context) .load(shop.products.get(position).getImageUrl()) .placeholder(android.R.drawable.ic_menu_upload_you_tube) .error(android.R.drawable.stat_notify_error) .diskCacheStrategy(DiskCacheStrategy.RESULT) .into(holder.ivProduct); 
} 
@Override public int getItemCount() 
{ 
    if (shop.products != null) { 
    return shop.products.size(); 
    } return 0; 
} 

public static class ProductViewHolder extends RecyclerView.ViewHolder { 
private TextView tvProductTitle, tvProductDescription; 
private ImageView ivProduct; 
public ProductViewHolder(View itemView) 
{ 
    super(itemView); 
    tvProductTitle = (TextView) itemView.findViewById(R.id.tvProductTitle); 
    tvProductDescription = (TextView) itemView.findViewById(R.id.tvProductDescription); 
ivProduct = (ImageView) itemView.findViewById(R.id.ivProduct); 
// Set onclickListener on image 
ivProduct.setOnCliCkListener(new onClickListener(){ 
    @Override 
    public void onClick(View v){ 
    Intent i = new Intent(context, ProductDetailsActivity.class);  
i.putExtra("product",  
shop.products.get(getAdapterPosition())); 
context.startActivity(i); 
} 
} 
} 
} 
public interface ClickListener { 
void onClick(View v, int position); 
    void onLongClick(View v, int position); 
} 
    } 
+0

完璧、このように動作します! – jlively

+0

お手伝いをしてください。あなたが望むなら、それを正答するために答えをアップアップすることができます。 –

0

をあなたが膨らんだのそれぞれのビューにクリックリスナーを追加することができますpublic onBindViewHolderの項目です。あなたはそれを考慮しましたか?

編集:これはあなたのやり方です。しかし効率については分かりませんが、これが私のやり方です。

関連する問題