多个适配器更新列表项的常见AsyncTask

时间:2016-01-09 06:44:03

标签: android interface android-asynctask network-programming adapter

我是Android新手,我有以下代码,显示适配器中的项目列表。

我有四个不同的适配器,我在这里调用一个comman AsyncTask 来更新结果。我实施了一个接口 ApiResponse并覆盖apiResponseProcessing()以获得结果。

在列表项"添加到购物车" 按钮添加到每一行。我要求服务器的那个按钮的 OnClick 。关于该响应的成功,我想用"添加到购物车"。

更新按钮

我有问题如何更新onBindViewHolder()中绑定的字符串。 我在该方法中取得了成功,但不知道如何更新该方法中点击的按钮。

这是我的适配器

/**
 * Adapter
 **/

public class AlbumPhotoDetailAdapter
        extends RecyclerView.Adapter<AlbumPhotoDetailAdapter.ViewHolder> implements ApiResponse {

    private final ArrayList<Photo> mValues;
    Album album;
    private Activity mContext;
    private int mMemberId;

    public AlbumPhotoDetailAdapter(Activity context, ArrayList<Photo> items) {
        mValues = items;
        this.mContext = context;
        mMemberId = MemberPreference.getMemberId(mContext);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.album_photo_detail_sub_view, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        final Photo photo = mValues.get(position);

        /**
         * Album Owner Name
         */
        String mOwnerName = photo.getOwnerName();
        String mOwnerProfilePic = photo.getOwnerImage();
        String mDateTime = photo.getDatetime();
        String mPrice = String.valueOf(photo.getPrice());

        /**
         * Price String
         */
        String priceStr = String.format(mContext.getString(R.string.string_dollar_price), mPrice);
        holder.mAlbumPhotoDetailPhotoPrice.setText(priceStr);

        /**
         * Main Image
         */
        Picasso.with(mContext).load(photo.getLink())
                .error(R.drawable.ic_place_holder_circle)
                .placeholder(R.drawable.ic_place_holder_circle)
                .transform(new ImageTransformation(holder.mAlbumPhotoDetailSubMainImage))
                .into(holder.mAlbumPhotoDetailSubMainImage);

        /**
         *  Owner Name and Profile Pic
         */
        holder.mAlbumPhotoDetailSubOwnerNameTextView.setText(mOwnerName);
        Picasso.with(mContext).load(mOwnerProfilePic)
                .error(R.drawable.ic_place_holder_circle)
                .placeholder(R.drawable.ic_place_holder_circle)
                .resize(100, 100)
                .transform(new CircleTransform())
                .into(holder.mAlbumPhotoDetailSubOwnerImage);

        mDateTime = mDateTime != null ? DateUtils.getNiceTime(mDateTime) : "----";
        holder.mAlbumPhotoDetailSubOwnerPostedTimeTextView.setText(mDateTime);       

        // Photo Add to cart.
        holder.mAddToCartButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(InternetConnection.checkConnection(mContext)) {
                    new BackgroundAsyncTask(mContext, (ApiResponse) mContext, mMemberId, photo.getId()).execute();
                } else {
                    DailyStudio.noInternetConnectionToast(mContext);
                }
            }
        });
    }


    @Override
    public int getItemCount() {
        return mValues.size();
    } 

    @Override
    public void apiResponseProcessing(String response) {
        Log.i(TAG,"Api Response : "+response);
        if(response.equals(Fields.JSON_SUCCESS)) {
        }
    }

    /**
     * View Holder
     */
    public static class ViewHolder extends RecyclerView.ViewHolder {

        public final View mView;

        private ImageView mAlbumPhotoDetailSubOwnerImage;
    private ImageView mAlbumPhotoDetailSubMainImage;
        private TextView mAlbumPhotoDetailSubOwnerNameTextView;
        private TextView mAlbumPhotoDetailSubOwnerPostedTimeTextView;     
        private TextView mAlbumPhotoDetailPhotoPrice;
        private TextView mAlbumPhotoDetailSubDescription;
        private Button mAddToCartButton;

        public ViewHolder(View view) {
            super(view);
            mView = view;

            mAlbumPhotoDetailSubOwnerImage = (ImageView) view.findViewById(R.id.album_photo_detail_sub_owner_image);
        mAlbumPhotoDetailSubMainImage = (ImageView) view.findViewById(R.id.album_photo_detail_sub_main_image);          
        mAlbumPhotoDetailSubOwnerNameTextView = (TextView) view.findViewById(R.id.album_photo_detail_sub_owner_name_text_view);
            mAlbumPhotoDetailSubOwnerPostedTimeTextView = (TextView) view.findViewById(R.id.album_photo_detail_sub_owner_posted_time_text_view);
            mAlbumPhotoDetailPhotoPrice = (TextView) view.findViewById(R.id.album_photo_detail_photo_price);
            mAlbumPhotoDetailSubDescription = (TextView) view.findViewById(R.id.album_photo_detail_sub_description);
            mAddToCartButton = (Button) view.findViewById(R.id.album_photo_detail_photo_add_to_cart_button);
        }
    }
}

这是我的界面

/**
* Interface..
*/

public interface ApiResponse {

    public void apiResponseProcessing(String response);

}

这是我的Background AsyncTask

/**
* Background AsyncTask...
*/

public class BackgroundAsyncTask extends AsyncTask<Void, Void, String> {

    private Context context;
    private String accessToken;
    private int memberId;
    private int photoId;
    private ApiResponse objIBaseApi;

    public BackgroundAsyncTask(Context context, ApiResponse apiResponse, int memberId, int photoId) {
        this.context = context;
        this.memberId = memberId;
        this.photoId = photoId;
        accessToken = MemberPreference.getAccessToken(context);
        this.objIBaseApi = apiResponse;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(Void... params) {

        JSONObject json = JSONParser.addToCartPhoto(accessToken, memberId, photoId);

        if(json != null) {
            Log.i(TAG,"First Json : "+json.toString());
            try {
                if (json.getString(Fields.RESULT).equalsIgnoreCase(Fields.JSON_SUCCESS)) {
                    return Fields.JSON_SUCCESS;
                } else if(json.getString(Fields.JSON_ERROR).equalsIgnoreCase(Fields.ERROR_ACCESS_DENIED)) {
                    String refreshToken = MemberPreference.getRefreshToken(context);

                    JSONObject newJSONObject = JSONParser.loginMemberWithRefreshToken(refreshToken, Integer.toString(memberId));

                    if(newJSONObject != null) {
                        if(newJSONObject.getString(Fields.JSON_ERROR).equalsIgnoreCase(Fields.ERROR_ACCESS_DENIED)) {
                            return Fields.ERROR_ACCESS_DENIED;
                        } else {
                            return Fields.JSON_SUCCESS;
                        }
                    } else
                        return Fields.ERROR_ACCESS_DENIED;

                } else {
                    return Fields.JSON_ERROR;
                }
            } catch (JSONException e) {
                e.printStackTrace();
                return Fields.JSON_ERROR;
            }
        }
        return Fields.JSON_ERROR;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        objIBaseApi.apiResponseProcessing(result);

    }
}

是否有任何解决方案或更好的方法可以做到这一点?

我们将不胜感激。谢谢。

2 个答案:

答案 0 :(得分:2)

您可以在适配器中使用的bean类中保留一个标志isAddedToCart变量(照片)。现在,只要用户点击“添加到购物车”按钮,就可以在你的asynctask中传递位置。获得成功后,您只需要从您在适配器中传递的bean列表中找到bean,并将标志isAddedToCart更改为true并通知您的适配器。以下是代码段: -

照片类

public class Photo{
private boolean isAddedToCart;

public void setAddedTOCart(boolean isAdded){
   isAddedToCart = isAdded;
}
public boolean isAddedToCart(){
   return isAddedToCart;
}

}

AlbumPhotoDetailAdapter onBindViewHolder

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    final Photo photo = mValues.get(position);

    /**
     * Album Owner Name
     */
    String mOwnerName = photo.getOwnerName();
    String mOwnerProfilePic = photo.getOwnerImage();
    String mDateTime = photo.getDatetime();
    String mPrice = String.valueOf(photo.getPrice());
    String isAdded = photo.isAddedToCart();

    /**
     * Price String
     */
    String priceStr = String.format(mContext.getString(R.string.string_dollar_price), mPrice);
    holder.mAlbumPhotoDetailPhotoPrice.setText(priceStr);

    /**
     * Main Image
     */
    Picasso.with(mContext).load(photo.getLink())
            .error(R.drawable.ic_place_holder_circle)
            .placeholder(R.drawable.ic_place_holder_circle)
            .transform(new ImageTransformation(holder.mAlbumPhotoDetailSubMainImage))
            .into(holder.mAlbumPhotoDetailSubMainImage);

    /**
     *  Owner Name and Profile Pic
     */
    holder.mAlbumPhotoDetailSubOwnerNameTextView.setText(mOwnerName);
    Picasso.with(mContext).load(mOwnerProfilePic)
            .error(R.drawable.ic_place_holder_circle)
            .placeholder(R.drawable.ic_place_holder_circle)
            .resize(100, 100)
            .transform(new CircleTransform())
            .into(holder.mAlbumPhotoDetailSubOwnerImage);

    mDateTime = mDateTime != null ? DateUtils.getNiceTime(mDateTime) : "----";
    holder.mAlbumPhotoDetailSubOwnerPostedTimeTextView.setText(mDateTime);       
if(isAdded){
   holder.mAddToCartButton.setText("Added TO Cart");
}else{
   holder.mAddToCartButton.setText("Add TO Cart");    
}
    // Photo Add to cart.
    holder.mAddToCartButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(InternetConnection.checkConnection(mContext)) {
                new BackgroundAsyncTask(mContext, (ApiResponse) mContext, mMemberId, photo.getId(),position).execute();
            } else {
                DailyStudio.noInternetConnectionToast(mContext);
            }
        }
    });
}

您的界面

public interface ApiResponse {
     public void apiResponseProcessing(String response,int position);
}

您的适配器apiResponceProcessing()

@Override
public void apiResponseProcessing(String response,int position) {
    Log.i(TAG,"Api Response : "+response);
    if(response.equals(Fields.JSON_SUCCESS)) {
        mValues.get(position).setAddedTOCart(true);
        notifyDataSetChange();
    }
}

最后你的 的 BackgroundAsyncTask

public class BackgroundAsyncTask extends AsyncTask<Void, Void, String> {

private Context context;
private String accessToken;
private int memberId;
private int photoId; 
private int mPosition;
private ApiResponse objIBaseApi;

public BackgroundAsyncTask(Context context, ApiResponse apiResponse, int memberId, int photoId,int position) {
    this.context = context;
    this.memberId = memberId;
    this.photoId = photoId;
    accessToken = MemberPreference.getAccessToken(context);
    this.objIBaseApi = apiResponse;
    this.mPosition = position;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected String doInBackground(Void... params) {

    JSONObject json = JSONParser.addToCartPhoto(accessToken, memberId, photoId);

    if(json != null) {
        Log.i(TAG,"First Json : "+json.toString());
        try {
            if (json.getString(Fields.RESULT).equalsIgnoreCase(Fields.JSON_SUCCESS)) {
                return Fields.JSON_SUCCESS;
            } else if(json.getString(Fields.JSON_ERROR).equalsIgnoreCase(Fields.ERROR_ACCESS_DENIED)) {
                String refreshToken = MemberPreference.getRefreshToken(context);

                JSONObject newJSONObject = JSONParser.loginMemberWithRefreshToken(refreshToken, Integer.toString(memberId));

                if(newJSONObject != null) {
                    if(newJSONObject.getString(Fields.JSON_ERROR).equalsIgnoreCase(Fields.ERROR_ACCESS_DENIED)) {
                        return Fields.ERROR_ACCESS_DENIED;
                    } else {
                        return Fields.JSON_SUCCESS;
                    }
                } else
                    return Fields.ERROR_ACCESS_DENIED;

            } else {
                return Fields.JSON_ERROR;
            }
        } catch (JSONException e) {
            e.printStackTrace();
            return Fields.JSON_ERROR;
        }
    }
    return Fields.JSON_ERROR;
}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);

    objIBaseApi.apiResponseProcessing(result,mPosition);

}

}

答案 1 :(得分:1)

首先在我看来,适配器不应该关心网络请求。但 在实质上给出答案,您可以尝试为您的apiResponseProcessing传递匿名类,方法与为按钮创建OnClickListener相同。它看起来像这样:

holder.mAddToCartButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(InternetConnection.checkConnection(mContext)) {
                new BackgroundAsyncTask(
                    mContext, 
                    new ApiResponse() {
                        @Override
                        public void apiResponseProcessing(String response) {
                            Log.i(TAG,"Api Response : "+response);
                            if(response.equals(Fields.JSON_SUCCESS)) {
                                // Here you can access you holder till it final 
                            }
                        }
                    }, 
                    mMemberId, 
                    photo.getId()).execute();
            } else {
                DailyStudio.noInternetConnectionToast(mContext);
            }
        }
});

但是像这样的代码看起来很混乱和意大利面条。正如我在开头所说,至少存在一种不同的方法来处理listview / recivleview中按钮的更改。我使用方法,其中适配器只关心构建具有给定数据的接口和委托按钮点击给其他人(在大多数情况下包含listview的活动)。关于按钮点击的简单方式通知活动是总线消息传递模式。我使用Otto event library。当委托接收有关按钮单击的通知时,它可以根据当前任务启动数据更改,然后启动listview重新加载或仅部分更新所需的行。

补充意见

  

尝试编写漂亮的代码。构造函数AlbumPhotoDetailAdapter具有不同的语法来分配实例变量。一个使用关键字而其他没有。通常你应该使用一种方法。

public AlbumPhotoDetailAdapter(Activity context, ArrayList<Photo> items) {
    this.values = items;
    this.context = context;
    this.memberId = MemberPreference.getMemberId(context);
}
  

相册实例变量没有访问修饰符指示。您应该知道,在java编程语言omitting access specifiers is not the same as private modifier中。