目前我正在使用Picasso此库作为图像加载。我正在尝试使用此库在listview中加载1000个图像,但这需要时间并且还会卡住我的应用程序。我能做些什么来获得流畅的用户体验?我在适配器中使用以下代码进行图像加载。
Picasso.with(context).load(new File(path + list.get(position)))
.centerCrop()
.resize(150, 150)
.error(R.mipmap.ic_launcher)
.into(img);
答案 0 :(得分:1)
将1000张图像加载到ListView会导致大量内存问题,并会降低设备速度。
我之前确实遇到过这样的问题,我发现解决方案是使用RecyclerView
代替ListView
。
RecyclerView
就是这样做,而不是每次创建和膨胀一个新视图,它会回收刚刚消失的视图并更改它的内容,以便将其添加到{{1的底部}}
请看下面的示例代码:
首先将RecyclerView
添加到RecyclerView
Gradle
将compile 'com.android.support:appcompat-v7:25.0.1'
compile 'com.android.support:recyclerview-v7:25.0.1'
添加到xml
RecyclerView
在<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animationCache="false"
android:scrollingCache="false"
android:smoothScrollbar="true" />
RecyclerView
Activity
然后创建您的RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(this);
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(mLayoutManager);
适配器
RecyclerView
然后只需将适配器设置为活动中的public class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.ViewHolder> {
Context context;
public ArrayList<EventObject> eventList;
private String category;
/**
* Viewholder class for view reuse
*/
public static class ViewHolder extends RecyclerView.ViewHolder {
private PEWImageView img_main;
private RelativeLayout layoutItem;
private TextView txt_event_name;
private TextView txt_event_details;
private TextView txt_going_to;
private View gradient_view;
/**
* Viewholder contructor where all assignments take place so this is only done once
* @param itemView
* @param context
*/
public ViewHolder(View itemView, Context context) {
super(itemView);
img_main = (PEWImageView) itemView.findViewById(R.id.img_main);
txt_event_details = (TextView) itemView.findViewById(R.id.txt_event_details);
txt_event_name = (TextView) itemView.findViewById(R.id.txt_event_name);
txt_going_to = (TextView) itemView.findViewById(R.id.txt_going_to);
gradient_view = itemView.findViewById(R.id.gradient_view);
layoutItem = (RelativeLayout) itemView.findViewById(R.id.rl_event_item);
txt_event_name.setTypeface(FontClass.getOpenSansBold(context));
txt_event_details.setTypeface(FontClass.getOpenSansLight(context));
txt_going_to.setTypeface(FontClass.getOpenSansLight(context));
}
/**
* Sets up UI for each item
* @param context
* @param eventObject
* @param category
* @throws JSONException
* @throws ParseException
*/
public void bindView(final Context context, final EventObject eventObject, String category) throws JSONException, ParseException {
/**
* Handles special characters
*/
txt_event_name.setText(Html.fromHtml(eventObject.getEventName()));
/**
* Checks if venue name contains the name of the town
*/
if (eventObject.getVenueName().contains(eventObject.getTown())) {
txt_event_details.setText(eventObject.getVenueName() + ", " + getFormattedDate(eventObject.getEventDate()));
} else {
txt_event_details.setText(eventObject.getVenueName() + ", " + eventObject.getTown() + ", " + getFormattedDate(eventObject.getEventDate()));
}
/**
* Checks if event should have yellow box above
*/
try {
if (eventObject.getFeeFreeStatus() == 1) {
txt_going_to.setVisibility(category.equalsIgnoreCase("no fees") ? View.GONE : View.VISIBLE);
txt_going_to.setText("Fee free tickets available");
} else {
txt_going_to.setVisibility(Integer.parseInt(eventObject.getGoingToCount()) >= 200 ? View.VISIBLE : View.GONE);
txt_going_to.setText("Popular event: " + eventObject.getGoingToCount() + " going");
}
} catch (Exception e){
e.printStackTrace();
txt_going_to.setVisibility(View.GONE);
}
/**
* Sets colour gradient over image
*/
if (eventObject.getHeaderHex() != null && !eventObject.getHeaderHex().equals("")) {
GradientDrawable gd = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{Color.TRANSPARENT, alterColor(Color.parseColor(eventObject.getHeaderHex()), 0.2f)});
gd.setCornerRadius(0f);
gradient_view.setBackground(gd);
}
layoutItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((HomeActivity) context).setEventProfileFrag(eventObject.getFullJsonObject(), null);
}
});
/**
* Loads image in to layout item
*/
Picasso.with(context)
.load(eventObject.getImageUrl())
.placeholder(R.drawable.ic_skiddle_placeholder)
.noFade()
.into(img_main);
}
/**
* Formats the date returned from the API
* @param dateString
* @return
* @throws ParseException
*/
private String getFormattedDate(String dateString) throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.UK);
Date newDate = format.parse(dateString);
format = new SimpleDateFormat("EEEE dd MMMM", Locale.UK);
String date = format.format(newDate);
return date;
}
}
/**
* Creates the view holder
* @param parent
* @param viewType
* @return
*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_event_list_item, parent, false);
return new ViewHolder(itemView, parent.getContext());
}
/**
* Binds the viewholder to the recyclerview
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
try {
holder.bindView(context, eventList.get(position), this.category);
} catch (JSONException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
/**
* Returns the item id
* @param position
* @return
*/
@Override
public long getItemId(int position) {
return position;
}
/**
* Returns the number of items in the adapter
* @return
*/
@Override
public int getItemCount() {
return eventList.size();
}
/**
* Constructor
* @param context
* @param eventList
* @param category
*/
public EventListAdapter(Context context, ArrayList<EventObject> eventList, String category) {
this.context = context;
this.eventList = eventList;
this.category = category;
setHasStableIds(true);
}
/**
* Method to add items to the adapter (for pagination)
* @param eventList
*/
public void addItems(ArrayList<EventObject> eventList) {
this.eventList.addAll(eventList);
notifyDataSetChanged();
}
/**
* Method to darken the head hex colour for the gradient overlay
* @param color
* @param factor
* @return
*/
public static int alterColor(int color, float factor) {
int a = (color & (0xFF << 24)) >> 24;
int r = (int) (((color & (0xFF << 16)) >> 16) * factor);
int g = (int) (((color & (0xFF << 8)) >> 8) * factor);
int b = (int) ((color & 0xFF) * factor);
return Color.argb(a, r, g, b);
}
}
。
您可以根据需要更改此适配器,但主要概念是在那里。
答案 1 :(得分:0)
答案 2 :(得分:0)
当我尝试开发图库应用并加载许多图像时,我也遇到了类似的问题。
对于解决方案,我已经改变了picasso版本如下,它运作得很好。
在您的应用级别build.gradle
中添加以下内容repositories {
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}
compile 'com.squareup.picasso:picasso:2.5.3-SNAPSHOT'