java - 将 RecyclerView 中的项目更改为 onBindViewHolder

标签 java android android-recyclerview adapter

在我的onBindViewHolder上,我用它来设置setImageResource

holder.card_image.setImageResource(image);

但是我的元素可以购买,所以我可以在我的 holder.view.setOnClickListener()

上购买该元素
 bp.purchase((Activity) mContext,model.getProduct_id());

所以,它转到这个方法:

bp = new BillingProcessor() new BillingProcessor.IBillingHandler() {
            @Override
            public void onProductPurchased(@NonNull String productId, @Nullable TransactionDetails details) {
                showToast("onProductPurchased: " + productId);
                //Purchased OK
                //WANT TO CHANGE THE IMAGE ONCE PURCHASE IS OK


            }
            @Override
            public void onBillingError(int errorCode, @Nullable Throwable error) {
                showToast("onBillingError: " + Integer.toString(errorCode));
            }
            @Override
            public void onBillingInitialized() {
                showToast("onBillingInitialized");
                readyToPurchase = true;

            }
            @Override
            public void onPurchaseHistoryRestored() {
                showToast("onPurchaseHistoryRestored");
                for(String sku : bp.listOwnedProducts())
                    Log.d("skuProducts", "Owned Managed Product: " + sku);
                for(String sku : bp.listOwnedSubscriptions())
                    Log.d("skuProducts", "Owned Subscription: " + sku);

            }
        });

如果我没有 onBindViewHolder,如何更改它?

我的适配器看起来像:

FirebaseRecyclerAdapter adapter = new   FirebaseRecyclerAdapter< CardPOJO, CardHolder>(options) {
        @Override
        public CardHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            //inflate the single recycler view layout(item)
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.card_product, parent, false);
            int width = parent.getMeasuredWidth() / 2;
            width -= mContext.getResources().getDimensionPixelSize(R.dimen._8sdp);
            final CardHolder cardViewHolder = new CardHolder(view,width);
            return cardViewHolder;
        }

        @Override
        public void onDataChanged() {
            super.onDataChanged();
            tv.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE);
        }

        @Override
        protected void onBindViewHolder(CardHolder holder, int position, final CardPOJO model) {
            holder.state.setText(model.getState());
            holder.cardName.setText(model.getName());
            switch (model.getState()){
                case "free":
                    //Img free
                    break;
                case "not_free":
                    //Img not free
                    break;
                default:
                    break;
            }
            holder.view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(model.getState().equals("free")){
                       //stuff
                    }
                    else{
                       //stuff
                        }
                        root_ref.child("PurchasedProducts").child(currentuser).addValueEventListener(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {
                                bp.purchase((Activity) mContext,model.getProduct_id()); //HERE I CALL THE PURCHASE SO IF IT'S OK I WANT TO DO SOMETHING LIKE holder.card_image.setImageResource(image);
                            }

                            @Override
                            public void onCancelled(DatabaseError databaseError) {

                            }
                        });
                    }

                }
            });


        }
    };
    adapter.startListening();
    products_recycler.setAdapter(adapter);

最佳答案

如果我正确地假设您想要更改 View 外观或在某些付款成功或失败时更改某些图像。

为此,您可以进行回调,它将为您提供 Activity 或 fragment 中的项目位置,从那里您可以进行服务器调用以进行购买,如果一切顺利的话。

当你让适配器构造函数传递回调时

final SomeAdapter obj = new SomeAdapter(this,new Callback(){
      @Override
      onPaymentRequested(int position, View view){
        //this will get called when you press click on image in bindviewholder
        bp = new BillingProcessor() new BillingProcessor.IBillingHandler() {
            @Override
            public void onProductPurchased(@NonNull String productId, @Nullable TransactionDetails details) {
                showToast("onProductPurchased: " + productId);
                //Purchased OK
                adapterModelList.get(position).setPayment(true);
                obj.notifyDataSetChanged();

            }
            @Override
            public void onBillingError(int errorCode, @Nullable Throwable error) {
                showToast("onBillingError: " + Integer.toString(errorCode));
            }
            @Override
            public void onBillingInitialized() {
                showToast("onBillingInitialized");
                readyToPurchase = true;

            }
            @Override
            public void onPurchaseHistoryRestored() {
                showToast("onPurchaseHistoryRestored");
                for(String sku : bp.listOwnedProducts())
                    Log.d("skuProducts", "Owned Managed Product: " + sku);
                for(String sku : bp.listOwnedSubscriptions())
                    Log.d("skuProducts", "Owned Subscription: " + sku);

            }
        });

    }
    });
recyclerView.setAdapter(obj);

因此,当您调用 obj.notifyDataSetChanged(); 时,它将使适配器再次绘制所有 View ,您可以根据收到的点击回调的 int 位置设置一些标志,并使其相应更改.

编辑=>07/12/2018:尝试了 Firebase 适配器并做了一些更改,因为代码不足以复制场景,但我对示例类做了一些更改,但基本的想法如下。

1:当用户单击 onBindViewHolder 中的 View 时,我们会收到一个回调,该回调给出了我们调用的 fragment 或 Activity 中的位置参数

2:现在我们处理付款,完成后我们还通过将 CardPojo 更新到该特定用户项目的服务器来对数据库 firebase 进行更改。

3:当我们更新服务器上的 CardPojo 时,我们还在card pojo 中设置了一个标志,它是 paymentSuccess 的 boolean 值,付款完成后将为 true。

4:由于我们的付款已完成,并且已与具有新标志数据的服务器同步,现在我们只需调用 firebaseRecycler.notifyItemChanged(position); 即可从服务器获取该特定的最新更新我们在回调中收到的位置。

5:现在populateViewHolder()为您提供一个cardpojo对象,您可以检查付款是否完成,然后您可以更改图像

所以这里是涉及的示例代码,我试图最好地匹配场景,希望你明白我在这里想要做什么。

所以首先创建一个监听器或回调

public interface CallBackInterface  {
    void onClick(int position,CardPOJO cardPOJO);
}

现在,无需在 Activity 或 Fragment 中初始化 FirebaseRecyclerAdapter,只需创建一个类并扩展它,这会分离您的 ui 逻辑,并为我们提供执行额外操作(例如添加回调)的可扩展性。

public class FirebaseRecycler extends FirebaseRecyclerAdapter<CardPOJO,CardHolder> {

CallBackInterface callBackInterface;

public FirebaseRecycler(Class<CardPOJO> modelClass, int modelLayout, Class<CardHolder> viewHolderClass, DatabaseReference ref) {
    super(modelClass, modelLayout, viewHolderClass, ref);
    this.callBackInterface = callBackInterface;
}

public FirebaseRecycler(Class<CardPOJO> modelClass, int modelLayout, Class<CardHolder> viewHolderClass, Query ref) {
    super(modelClass, modelLayout, viewHolderClass, ref);
    this.callBackInterface = callBackInterface;
}

@Override
public CardHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    //your inflater logic goes here
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_product, parent, false);
    CardHolder cardHolder = new CardHolder(view);
    return cardHolder;
}

@Override
protected void populateViewHolder(CardHolder viewHolder, final CardPOJO model, final int position) {
    //your populate logic
    //your existing code here

    if (model.isPaymentDone){
        //set payment success image holder.card_image.setImageResource(image);

    }else{
        //set payment failure image

    }

    //setting the card click listener
    viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //we have the card click listener, we will start the payment processing in activity
            callBackInterface.onClick(position,model);
        }
    });
}

public void setCallBackInterface(CallBackInterface callBackInterface) {
    this.callBackInterface = callBackInterface;
}

}

现在几乎所有事情都已完成,我们需要调用此自定义 Firebase 适配器并传递所需的内容,它将完成其工作。

  @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final DatabaseReference mDatabaseRef = FirebaseDatabase.getInstance().getReference();
    /*
    if you have any other database child then you can refer to it using
    DatabaseReference child = mDatabaseRef.child("yourchilddatabase");
    and pass this to the last argument
     */

    final FirebaseRecycler firebaseRecycler = new FirebaseRecycler(CardPOJO.class, R.layout.card_product, CardHolder.class, mDatabaseRef);
    firebaseRecycler.setCallBackInterface(new CallBackInterface() {
        @Override
        public void onClick(final int position, final CardPOJO cardPOJO) {
            //start processing the payment

            bp = new BillingProcessor() new BillingProcessor.IBillingHandler() {
                @Override
                public void onProductPurchased(@NonNull String productId, @Nullable TransactionDetails details) {
                    /**
                     *when you have processed the payment just enable the flag on server database by having a extra boolean flag for this
                     * and check in onBindViewHolder if this is enabled if so then replace your image
                     * updating the values on server, you can handle it according to your user case
                     */
                    cardPOJO.setPaymentDone(true);
                    mDatabaseRef.push().setValue(cardPOJO);
                    firebaseRecycler.notifyItemChanged(position);

                }

                @Override
                public void onBillingError(int errorCode, @Nullable Throwable error) {
                    //existing logic
                }

                @Override
                public void onBillingInitialized() {
                    //existing logic
                }

                @Override
                public void onPurchaseHistoryRestored() {
                    //existing logic
                }
            };

        }
    });

}

这演示了您可以根据您的要求对其进行修补的基本逻辑。

关于java - 将 RecyclerView 中的项目更改为 onBindViewHolder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48116701/

相关文章:

android - 如何在 Kotlin 中创建具体化类型的对象

java - Visual Studio Code JAVA 中的条件断点

java - getter 和 setter 的意义何在?

java - Spring java中的ToString和EqualsAndHashCode注解

java - ConstraintLayout 内 RecyclerView 内的 Center ProgressBar

android - 改造响应给出错误数据

java - 计算最后一个星期天前1周和今天到最后一个星期日

android - 打开带有 Google Play 商店链接的 Android 应用

java - 如何在非父 Activity 中更改小部件

java - 从对话框 fragment 返回后,工具栏 View 引用变为空