Загрузка 1000 изображений в к ListView собираются вызвать много проблем с памятью и замедлят ваше устройство.
У меня на самом деле была проблема, как это раньше, и я нашел решение использовать RecyclerView
вместо ListView
.
Посмотрите на этот пример кода ниже:
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
Initialise в 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
в деятельности.
Вы можете изменить этот адаптер так, как вам это нужно, но основная концепция есть.