GridView使用HTTP响应呈现很长时间

时间:2016-04-04 09:07:07

标签: android http listview

我是Android开发的初学者。我已将此库用于http请求https://github.com/loopj/android-async-http

然后我在GridView中渲染响应JSON需要很长时间。我使用进度对话框作为预加载器,但在呈现listview之前已将其删除。我怎么能解决这个问题?谢谢。

以下是此GridView的屏幕截图。

enter image description here

以下是此活动的实施。

public class LikesActivity extends BottomBarActivity //some custom activity {
List<Anticafe> mAnticafes = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_likes);

        /*some code*/



        Request.post(Constants.POST_SEARCH_API_LINK, params, new AsyncHttpResponseHandler() {
                @Override
                public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                    Gson gson = new GsonBuilder().create();
                    Request request = gson.fromJson(new String(responseBody), Request.class);

                    mAnticafes = request.getAnticafes();
                    renderListView()
                }

                @Override
                public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                    hideProcessDialog();
                }
            });


    }

    private void renderListView() {
         GridView likesList = (GridView) findViewById(R.id.likes_list);
        AnticafeAdapter anticafeAdapter = new AnticafeAdapter(this, mAnticafes); 
        anticafeAdapter.setWidth(getWidth());
        likesList.setAdapter(anticafeAdapter);
    }
}

这是适配器的完整实现。

public class AnticafeAdapter extends BaseAdapter{

    public static final String TAG = "image-request";
    private Context mContext;
    private List<Anticafe> mAnticafes = new ArrayList<>();
    private Client mClient;
    private View mConvertView;
    private int mWidth;

    public AnticafeAdapter(Context context, List<Anticafe> anticafes) {
        mContext = context;
        mAnticafes = anticafes;
    }

    public void setWidth(int mWidth) {
        this.mWidth = (int) (mWidth / 4.7);
    }

    @Override
    public int getCount() {
        return mAnticafes.size();
    }

    @Override
    public Anticafe getItem(int position) {
        return mAnticafes.get(position);
    }

    @Override
    public long getItemId(int position) {
        return getItem(position).getId();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        final Anticafe anticafe = getItem(position);
        mClient = AnticafeApplication.getInstanse().getClient();
        mConvertView = convertView;
        final ProgressDialog processDialog = new ProgressDialog(mContext);

        processDialog.setMessage("Информация обновляется. Пожалуйста, подождите.");

        if(mConvertView == null) {
            mConvertView = LayoutInflater.from(mContext).inflate(R.layout.adapter_popular, null);
        }

        ImageView cover = (ImageView) mConvertView.findViewById(R.id.cover);
        CircularImageView logo = (CircularImageView) mConvertView.findViewById(R.id.logo);
        final ImageView like = (ImageView) mConvertView.findViewById(R.id.like);
        final TextView likesCount = (TextView) mConvertView.findViewById(R.id.likes_count);
        TextView name = (TextView) mConvertView.findViewById(R.id.name);
        TextView price = (TextView) mConvertView.findViewById(R.id.price);

        if(mClient != null) {
            final boolean liked = mClient.containsLike(anticafe.getId());
            if(liked) {
                like.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_like));
            } else {
                like.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_unlike));
            }
        } else {
            like.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_unlike));
        }

        likesCount.setText(String.valueOf(anticafe.getTotalLikes()));
        name.setText(anticafe.getName());
        price.setText(anticafe.getPrices());

        Picasso.with(mContext).load(anticafe.getAttachment().getCover()).networkPolicy(NetworkPolicy.OFFLINE).into(cover);
        Picasso.with(mContext).load(anticafe.getAttachment().getLogo()).resize(mWidth, mWidth).into(logo);

        likeMechanism(anticafe, processDialog, like, likesCount);

        name.setOnClickListener(anticafeOpenActivityEvent(anticafe.getId()));
        price.setOnClickListener(anticafeOpenActivityEvent(anticafe.getId()));
        logo.setOnClickListener(anticafeOpenActivityEvent(anticafe.getId()));
        cover.setOnClickListener(anticafeOpenActivityEvent(anticafe.getId()));

        BottomBarActivity activity = (BottomBarActivity) this.mContext;
        activity.hideProcessDialog();

        return mConvertView;
    }

    private void likeMechanism(final Anticafe anticafe, final ProgressDialog processDialog, final ImageView like, final TextView likesCount) {
        like.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                if (mClient == null) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
                    builder.setTitle("Вы не авторизованы")
                            .setMessage("До тех пор, пока вы не пройдете авторизацию, вы не сможете пользоваться некоторым функционалом нашего приложение. Авторизация займет всего лишь пару минут.")
                            .setCancelable(false)
                            .setNegativeButton("Скрыть", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                }
                            })
                            .setPositiveButton("Авторизоваться", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    Intent intent = new Intent(mContext, AuthActivity.class);
                                    mContext.startActivity(intent);
                                    Activity activity = ((Activity) mContext);
                                    activity.overridePendingTransition(R.anim.slide_in_left, R.anim.slide_in_right);
                                }
                            });

                    AlertDialog dialog = builder.create();
                    dialog.show();

                } else {

                    processDialog.show();

                    RequestParams params = new RequestParams();
                    params.add("anticafe_id", anticafe.getId() + "");
                    AuthedRequest.post(Constants.LIKE_API_LINK, params, new AsyncHttpResponseHandler() {
                        @Override
                        public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                            processDialog.hide();
                            Gson gson = new GsonBuilder().create();
                            try {
                                LikeResponse response = gson.fromJson(new String(responseBody, Constants.UTF_8), LikeResponse.class);
                                if (response.getLikeStatus().equals("unliked")) {
                                    like.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_unlike));
                                } else if (response.getLikeStatus().equals("liked")) {
                                    like.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_like));
                                }
                                likesCount.setText(String.valueOf(response.getTotalLikes()));
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            } finally {
                                processDialog.hide();
                            }
                        }

                        @Override
                        public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                            try {
                                Log.d("json", "onSuccess: " + new String(responseBody, Constants.UTF_8));
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            } finally {
                                processDialog.hide();
                            }
                        }

                    });
                }
            }
        });
    }

    private OnClickListener anticafeOpenActivityEvent(final int id) {
        return new OnClickListener() {
            @Override
            public void onClick(View v) {
                Bundle bundle = new Bundle();
                bundle.putInt("entity_id", id);
                ((BottomBarActivity) mContext).openNewActivity(AnticafeActivity.class, bundle);
            }
        };
    }

    private static class LikeResponse {

        @SerializedName("status")
        @Expose
        private Integer status;
        @SerializedName("error")
        @Expose
        private Boolean error;
        @SerializedName("likeStatus")
        @Expose
        private String likeStatus;
        @SerializedName("totalLikes")
        @Expose
        private Integer totalLikes;

        public LikeResponse(Integer status, Boolean error, String likeStatus, Integer totalLikes) {
            this.status = status;
            this.error = error;
            this.likeStatus = likeStatus;
            this.totalLikes = totalLikes;
        }

        /**
         *
         * @return
         * The status
         */
        public Integer getStatus() {
            return status;
        }

        /**
         *
         * @param status
         * The status
         */
        public void setStatus(Integer status) {
            this.status = status;
        }

        /**
         *
         * @return
         * The error
         */
        public Boolean getError() {
            return error;
        }

        /**
         *
         * @param error
         * The error
         */
        public void setError(Boolean error) {
            this.error = error;
        }

        /**
         *
         * @return
         * The likeStatus
         */
        public String getLikeStatus() {
            return likeStatus;
        }

        /**
         *
         * @param likeStatus
         * The likeStatus
         */
        public void setLikeStatus(String likeStatus) {
            this.likeStatus = likeStatus;
        }

        /**
         *
         * @return
         * The totalLikes
         */
        public Integer getTotalLikes() {
            return totalLikes;
        }

        /**
         *
         * @param totalLikes
         * The totalLikes
         */
        public void setTotalLikes(Integer totalLikes) {
            this.totalLikes = totalLikes;
        }

    }
}

1 个答案:

答案 0 :(得分:2)

你没有显示任何代码来确切地说出你的问题 但无论如何最好使用第三方库来加载来自网络的图像,例如毕加索:
http://square.github.io/picasso
这个库可以平滑地加载您的图像并自行管理缓存 的更新:
其他选项是你不要在你的适配器类的getView方法中使用viewHolder设计模式 在当前代码中,您在gridView的每个单元格中调用findViewById方法,但您必须首次调用它。 要解决此问题,您应该使用viewHolder设计模式。

带有视图持有者的getView方法示例:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolderItem viewHolder;

    /*
     * The convertView argument is essentially a "ScrapView" as described is Lucas post 
     * http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/
     * It will have a non-null value when ListView is asking you recycle the row layout. 
     * So, when convertView is not null, you should simply update its contents instead of inflating a new row layout.
     */
    if(convertView==null){

        // inflate the layout
        LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
        convertView = inflater.inflate(layoutResourceId, parent, false);

        // well set up the ViewHolder
        viewHolder = new ViewHolderItem();
        viewHolder.textViewItem = (TextView) convertView.findViewById(R.id.textViewItem);

        // store the holder with the view.
        convertView.setTag(viewHolder);

    }else{
        // we've just avoided calling findViewById() on resource everytime
        // just use the viewHolder
        viewHolder = (ViewHolderItem) convertView.getTag();
    }

    // object item based on the position
    ObjectItem objectItem = data[position];

    // assign values if the object is not null
    if(objectItem != null) {
        // get the TextView from the ViewHolder and then set the text (item name) and tag (item ID) values
        viewHolder.textViewItem.setText(objectItem.itemName);
        viewHolder.textViewItem.setTag(objectItem.itemId);
    }

    return convertView;

}

View holder类的示例(在此类中定义视图元素):

static class ViewHolderItem {
    TextView textViewItem;
}

了解更多信息,请参阅:
https://www.javacodegeeks.com/2013/09/android-viewholder-pattern-example.html