加载1000张图像是要造成大量的内存问题,并会减慢您的设备。
我以前有过这样的问题,我发现解决方案是使用RecyclerView
而不是ListView
。
A RecyclerView
就是这样做的,它不是每次创建和膨胀一个新视图,而是回收刚刚消失的视图并更改它的内容,因此可以将其添加到RecyclerView
的底部。
看一看下面这个示例代码:
首先添加RecyclerView
到Gradle
compile 'com.android.support:appcompat-v7:25.0.1'
compile 'com.android.support:recyclerview-v7:25.0.1'
添加RecyclerView
为xml
<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);
}
}
然后,只需将适配器设置为RecyclerView
了活动。
您可以更改此适配器以了解您的需要,但主要概念在此处。