【发布时间】:2015-07-18 07:31:31
【问题描述】:
在我的 android 应用程序中,主页上有一个 recyclerview,其中包含作为每个项目的卡片视图。首先,我调用 ParseServer 来获取服务器上的数据并将其传递给 recyclerview 适配器。我将图像 url 以及其他详细信息传递给适配器类。 在我的 MainActivity.java 中
Parse.initialize(this, "key1", "key2");
ParsePush.subscribeInBackground("", new SaveCallback() {
@Override
public void done(ParseException e) {
if (e == null) {
Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
} else {
Log.e("com.parse.push", "failed to subscribe for push", e);
}
}
});
if(haveNetworkConnection()){
new task().execute();
mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
从服务器获取数据的类任务:
public class task extends AsyncTask<Void, Void, Void>{
ProgressDialog mProgressDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
rel.setVisibility(View.VISIBLE);
pro.setVisibility(View.VISIBLE);
titles.clear();
images.clear();
venues.clear();
timings.clear();
urgent.clear();
}
@Override
protected Void doInBackground(Void... params) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("notices");
try {
List<ParseObject> ob = query.find();
for(ParseObject obj:ob){
String str = obj.getString("title");
String str1 = obj.getString("venue");
String str2 = obj.getString("timing");
ParseFile file = obj.getParseFile("images");
String str3 = obj.getString("urgent");
String url;
if(file!=null)
url = file.getUrl();
else{
url = "https://www.medidirect.com.au/MEDIstores/_images/no-thumb.png";
}
titles.add(str);
images.add(url);
venues.add(str1);
timings.add(str2);
urgent.add(str3);
}
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
AdapNotice mAdapter = new AdapNotice(MainActivity.this,titles,images,venues,timings,urgent);
if(titles.size()<1)
Toast.makeText(MainActivity.this, "Oops, Something went wrong. Please try again", 300).show();
mRecyclerView.setAdapter(mAdapter);
pro.setVisibility(View.GONE);
rel.setVisibility(View.GONE);
}
}
在 Recyclerview 适配器的 AdapNotice 类中:
public class AdapNotice extends RecyclerView.Adapter<AdapNotice.ViewHolder>{
Activity activity;
ArrayList<String> _titles = new ArrayList<String>();
ArrayList<String> _images = new ArrayList<String>();
ArrayList<String> _venues = new ArrayList<String>();
ArrayList<String> _timings = new ArrayList<String>();
ArrayList<String> _urgents = new ArrayList<String>();
private int lastPosition = -1;
int pos;
public AdapNotice(Activity a, ArrayList<String> titles, ArrayList<String> images, ArrayList<String> venues, ArrayList<String> timings, ArrayList<String> urgent) {
activity = a;
_titles = titles;
_images = images;
_venues = venues;
_timings = timings;
_urgents = urgent;
}
public static class ViewHolder extends RecyclerView.ViewHolder{
// each data item is just a string in this case
public TextView title;
public ImageView imgview,urgent;
public TextView venue,venuetext,abctext;
public TextView timing,timingtext,abc1text;
public ViewHolder(View v) {
super(v);
title = (TextView) v.findViewById(R.id.title);
imgview = (ImageView) v.findViewById(R.id.img_notice);
venue = (TextView) v.findViewById(R.id.venue);
timing = (TextView) v.findViewById(R.id.timing);
venuetext = (TextView)v.findViewById(R.id.venuetext);
abctext = (TextView)v.findViewById(R.id.abctext);
timingtext = (TextView)v.findViewById(R.id.timingtext);
abc1text = (TextView)v.findViewById(R.id.abc1text);
urgent = (ImageView)v.findViewById(R.id.urgentstar);
}
}
@Override
public int getItemCount() {
// TODO Auto-generated method stub
if(_titles.size()<=0)
return 0;
return _titles.size();
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
// TODO Auto-generated method stub
try{
holder.title.setText(_titles.get(position));
if(_urgents.get(position).contains("yes")){
holder.urgent.setVisibility(View.VISIBLE);
}
pos = position;
if(!_venues.get(position).contentEquals("---")){
holder.venuetext.setVisibility(View.VISIBLE);
holder.venue.setVisibility(View.VISIBLE);
holder.abctext.setVisibility(View.VISIBLE);
holder.venue.setText(_venues.get(position));
}
if(!_timings.get(position).contentEquals("---")){
holder.timingtext.setVisibility(View.VISIBLE);
holder.timing.setVisibility(View.VISIBLE);
holder.abc1text.setVisibility(View.VISIBLE);
holder.timing.setText(_timings.get(position));
}
Target target = new Target() {
@Override
public void onPrepareLoad(Drawable arg0) {
// TODO Auto-generated method stub
Animation anim = AnimationUtils.loadAnimation(activity, R.anim.rotate);
holder.imgview.setImageResource(R.drawable.loading);
holder.imgview.startAnimation(anim);
}
@Override
public void onBitmapLoaded(Bitmap arg0, LoadedFrom arg1) {
// TODO Auto-generated method stub
holder.imgview.clearAnimation();
holder.imgview.setImageBitmap(arg0);
Log.i("completed", pos+" completed");
storeDB obj = new storeDB(_titles.get(pos), _venues.get(pos), _timings.get(pos), DbBitmapUtility.getBytes(arg0), _urgents.get(pos));
obj.execute();
}
@Override
public void onBitmapFailed(Drawable arg0) {
// TODO Auto-generated method stub
holder.imgview.clearAnimation();
holder.imgview.setImageResource(R.drawable.error);
}
};
Picasso.with(activity).load(_images.get(position)).into(target);
}catch(Exception e){
e.printStackTrace();
}
}
private class storeDB extends AsyncTask<Void, Void, Void>{
String title,venue,timing,urgent;
byte[] image;
public storeDB(String one, String two, String three, byte[] four, String five){
title = one;
venue = two;
timing = three;
image = four;
urgent = five;
}
@Override
protected Void doInBackground(Void... params) {
SQLiteHandler handler = new SQLiteHandler(activity);
handler.addNotice(title, venue, timing, image, urgent);
handler.close();
return null;
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int arg1) {
View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.item, parent, false);
Animation animation = AnimationUtils.loadAnimation(activity, (arg1>lastPosition)?R.anim.up_from_bottom:R.anim.down_from_top);
v.startAnimation(animation);
ViewHolder vh = new ViewHolder(v);
return vh;
}
}
我将图像 url 传递给 picasso 库,该库将图像加载到目标中。直到毕加索没有提取图像,我正在显示另一个加载图像并赋予它旋转动画效果。
有时,即使图像是由毕加索加载的,它也不会显示在 imageview 中。我知道这是因为单击该 imageview 时,完整的图像会加载到另一个可以正常工作的活动中。旋转动画停止并且加载的图像也未显示在 imageview 中。此外,在加载 imageview 时,主视图有时会冻结。
那么,我该如何解决这个问题,让我的应用运行更流畅?
提前致谢。
更新我发现冻结问题是由于对目标的弱引用。我通过强大的参考解决了它,但我该如何解决悬挂问题?当我滚动时,应用程序会挂起一段时间。
【问题讨论】:
-
Picasso 已经缓存了图像,无需将其存储在 SQLlite 中,另外尝试缩小加载到图像视图中的图像
Picasso.with(context) .load(url) .resize(50, 50) .centerCrop() .into(imageView) -
我在用户离线时使用 sqlite。缓存不会一直留在那里吗?
-
Android 系统需要回收内存时不会清理缓存,因此如果您需要 SQLlite 存储图像,请查看存储 blob。
-
我已经这样做了。这很好用。图像已成功存储为 blob
-
在主页上,我在较小的图像视图中显示该图像。单击该按钮后,将打开另一个活动,其中包含完整大小的图像。那么,如果我使用 .resize ,如何管理两种尺寸的图像加载?
标签: android android-layout picasso android-recyclerview android-cardview