如何使用Android中的Piccaso图像加载库平滑图像加载?

时间:2017-02-10 06:54:10

标签: android image listview load android-imageview

目前我正在使用Picasso此库作为图像加载。我正在尝试使用此库在listview中加载1000个图像,但这需要时间并且还会卡住我的应用程序。我能做些什么来获得流畅的用户体验?我在适配器中使用以下代码进行图像加载。

Picasso.with(context).load(new File(path + list.get(position)))
                     .centerCrop()
                     .resize(150, 150)
                     .error(R.mipmap.ic_launcher)
                     .into(img);

3 个答案:

答案 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)

尝试使用

  

滑行: - https://github.com/bumptech/glide

取代毕加索

答案 2 :(得分:0)

当我尝试开发图库应用并加载许多图像时,我也遇到了类似的问题。

对于解决方案,我已经改变了picasso版本如下,它运作得很好。

在您的应用级别build.gradle

中添加以下内容
repositories {
    maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}

compile 'com.squareup.picasso:picasso:2.5.3-SNAPSHOT'