在完成asynctask

时间:2016-08-14 16:20:39

标签: java android listview android-asynctask adapter

我一直在四处寻找,但我没有运气,所以我想对此有所了解,特别是要知道我是否走错了方向。

我有一个片段实例化一个适配器,向它传递一个对象的arraylist。对象列表引用必须从服务器检索以便显示的其他资源。因此,对于arraylist的每个对象,在适配器中,我调用asynctask来检索这些信息并填充适配器项。

不幸的是,这只导致arraylsit的最后一个元素包含所有信息,而另一个(在我的例子中我只有两个元素在列表中)是空的。我的感觉是我重写了两次相同的适配器项目,因此我只看到最后检索到的对象。

我的适配器使用ViewHolder设计模式,因此,在函数getView中,我实例化ViewHolderItem私有类的对象,该对象包含对所有布局元素的引用。然后我在所有onPostExecute中使用此viewHolderItem来填充适配器项。

这是我的ViewHolder项目的代码:

private static class ViewHolderItem{
    protected Button leaveFeedback, accept, reject;
    protected LinearLayout userInfo, rideInfo, pickupLayout, buttons;
    protected TextView pickupTimeText;
    protected PickupTime pickupTime;
}

这是我的getView,它收集视图引用,设置viewholderitem并启动asynctasks(注释检索乘客信息后的行):

@Override
public View getView(int i, View view, ViewGroup viewGroup) {

    // First let's verify the view is not null
    if (view == null) {
        // This a new view we inflate the new layout
        LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.ride_passenger_item, viewGroup, false);
        viewHolderItem = new ViewHolderItem();

        viewHolderItem.userInfo = (LinearLayout) view.findViewById(R.id.user_info);
        viewHolderItem.rideInfo = (LinearLayout) view.findViewById(R.id.ride_info);
        viewHolderItem.buttons = (LinearLayout) view.findViewById(R.id.btns);
        viewHolderItem.leaveFeedback = (Button) view.findViewById(R.id.leave_feedback);
        viewHolderItem.pickupLayout = (LinearLayout) view.findViewById(R.id.pickup_layout);
        viewHolderItem.pickupTimeText = (TextView) view.findViewById(R.id.pickup_time);
        viewHolderItem.accept = (Button) view.findViewById(R.id.accept);
        viewHolderItem.reject = (Button) view.findViewById(R.id.reject);

        // store the holder with the view.
        view.setTag(viewHolderItem);
    }
    else{
        // we've just avoided calling findViewById() on resource everytime
        // just use the viewHolder
        viewHolderItem = (ViewHolderItem) view.getTag();
    }

    final Passengership passengership = passengerships.get(i);

    /** retrieve passenger info **/
    new GetDemand().execute(demandAPI.getDemand());
    new GetPassenger().execute(userAPI.getUser(passengership.getPassenger()));
    new GetRide().execute(rideAPI.getRide());

    /**
     * if we are displaying pending passenger request, proposed by the driver
     * we need to enable the accept reject button
     **/
    if(type.equals(Status.PENDING) && !passengership.isProposedByDriver())
        buildAcceptRejectButtons(passengership);

    this.passengershipID = passengership.getId();
    return view;
}

这是我的AsyncTask类之一:

/**
 * Download the JSON of the demand
 */
private class GetDemand extends GetRequest {

    @Override
    protected void onPostExecute(ServerResponseObject serverResponseObject){
        Demand demand = GsonCustomBuilder.getGson().fromJson(
                serverResponseObject.getJSONObject().toString(), Demand.class);
        demand.populateView(viewHolderItem.rideInfo);
    }
}

demand.populateView()基本上是一个函数,我传递包含视图引用的viewHolderItem,以便我可以在其中填充信息。

1 个答案:

答案 0 :(得分:0)

原来我没有正确使用适配器但是由于@greenapps输入我设法解决了我的问题。

基本上我在getView函数中移动了变量viewHolderItem,现在我通过构造函数将它传递给我的所有AsyncTasks,因此一旦从服务器获得结果,就可以使用它来填充适配器项。

例如,在上述修改之后,这是我的AsyncTask类之一:

/**
 * Download the JSON of the demand
 */
private class GetDemand extends GetRequest {

    private int passengershipID;
    private ViewHolderItem viewHolderItem;

    public GetDemand(int passengershipID, ViewHolderItem viewHolderItem){
        this.passengershipID = passengershipID;
        this.viewHolderItem = viewHolderItem;
    }

    @Override
    protected void onPostExecute(ServerResponseObject serverResponseObject){
        Demand demand = GsonCustomBuilder.getGson().fromJson(
                serverResponseObject.getJSONObject().toString(), Demand.class);
        Passengership passengership = passengershipsHashMap.get(passengershipID);
        passengership.setDemand(demand);
        demand.populateView(viewHolderItem.rideInfo);
    }
}

正如您在代码中看到的,我使用了构造函数来传递给AsyncTask的viewHolderItem。最后,在onPostExecute中,我使用viewHolderItem来填充检索到的信息。