在我的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);
最佳答案
如果我假设正确,那么您要更改视图外观或更改某些图像(如果成功完成某笔付款则失败)。
为此,您可以有一个回调,该回调将为您提供活动中的商品位置或从那里返回片段,您可以进行服务器调用以进行购买,如果一切顺利。
当您使适配器构造函数传递回调时
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();它将使适配器再次绘制所有视图,您可以在其中根据单击回调收到的int位置设置一些标志,并进行相应的更改。
编辑=> 07/12/2018:尝试了Firebase适配器并进行了很少的更改,因为代码不足以复制场景,但是我对示例类进行了少量更改,但基本思想如下所示。
1:当用户单击onBindViewHolder中的视图时,我们会收到一个回调,该回调给出了片段或活动中我们要调用的位置的位置参数
2:现在,我们处理付款,完成后,我们也通过将CardPojo更新到该特定用户项目的服务器来更改Database firebase。
3:当我们在服务器上更新CardPojo时,我们还在card pojo中设置了一个标志,该标志是paymentSuccess的布尔值,当付款完成时该标志为true。
4:由于我们的付款已经完成,并且已与服务器同步并带有新的标志数据,所以现在我们可以调用
firebaseRecycler.notifyItemChanged(position);
,它将从服务器上获取我们在回调中收到的特定头寸的最新更新。5:现在populateViewHolder()为您提供了一个cardpojo对象,您可以检查是否付款,然后可以更改图像
因此,这里是示例代码,我尽力匹配该场景,希望您理解我在这里尝试做的事情。
所以首先创建一个监听器或回调
public interface CallBackInterface {
void onClick(int position,CardPOJO cardPOJO);
}
现在,您无需在活动或片段中初始化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
}
};
}
});
}
这说明了您可以根据需要对其进行修补的基本逻辑。