我是Android开发的初学者。我已将此库用于http请求https://github.com/loopj/android-async-http。
然后我在GridView中渲染响应JSON需要很长时间。我使用进度对话框作为预加载器,但在呈现listview之前已将其删除。我怎么能解决这个问题?谢谢。
以下是此GridView的屏幕截图。
以下是此活动的实施。
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;
}
}
}
答案 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