使我的RecyclerView表现更好

时间:2018-06-25 23:41:42

标签: android android-recyclerview

我的应用程序完全是关于性能的,所以我真的很想尽可能地优化此RecyclerView。我测量了每个部分完成所需的时间,整个过程需要大约150ms的加载时间。这是相关代码:

public class AppAdapter extends RecyclerView.Adapter<AppAdapter.TabViewHolder> {

    private Context context;
    private MenuActivity menuActivity;
    private Intent intent;
    private ArrayList<String> stringys = new ArrayList<>();

    public void setUpAdapter(Context mContext, MenuActivity mMenuActivity, Intent mIntent, ArrayList<String> mString) {
        this.menuActivity = mMenuActivity;
        this.context = mContext;
        this.intent = mIntent;
        stringys.addAll(mString);
    }

    @Override
    public TabViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);
        Log.d(TAG, "CreatingViewholder " + "Time: " + menuActivity.deltaTime());
        View view = inflater.inflate(R.layout.item_tab, parent, false); //Here is where the wait happens
        Log.d(TAG, "ViewHolderCreated " + "Time: " + menuActivity.deltaTime()); 
        return new TabViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull TabViewHolder holder, int position) {
        holder.bind(position, holder);
    }

    @Override
    public int getItemCount() {
        return stringys.size();
    }

    class TabViewHolder extends RecyclerView.ViewHolder {

        TextView text;
        ImageView image;

        TabViewHolder(View itemView) {
            super(itemView);
            text = itemView.findViewById(R.id.label);
            image = itemView.findViewById(R.id.icon);
        }

        void bind(int position, TabViewHolder holder) {
            new LongOperation(text, image).execute(stringys.get(position));
        }
    }
    private class LongOperation extends AsyncTask<String, Void, Void> {

        TextView text;
        ImageView image;
        CharSequence textToSet;
        Drawable imageToSet;

        public LongOperation(TextView text, ImageView image) {
            super();
            this.text = text;
            this.image = image;
        }

        @Override
        protected Void doInBackground(String... params) {
            textToSet = params[0].getTitle(context.getDefaultSharedPreferences());
            imageToSet = params[0].getIcon(context.getDefaultSharedPreferences());
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            text.setText(textToSet);
            image.setImageDrawable(imageToSet);
        }
    }
}

对此我有几个想法/问题:

  1. 是否可以重用此ViewHolder?我每次都使用它,每次充气大约需要5毫秒,因为这是一个网格,所以加起来很快,因为当我启动它时,我要装载约40个支架。
  2. 如果有帮助,我也准备使用另一种观点。我选择了recyclerview,因为它最适合imo,但是如果有更好的视图,我可以更改为该视图。
  3. 如果我使用线性布局并将当前使用的4个ViewHolder彼此相邻放置,这会有所帮助吗?那我的时间会减少4吗?
  4. 在asynctask中,我两次致电context.getDefaultSharedPreferences()。如果我做了一次并将其作为变量传递,它将加载得更快(异步部分)吗?
  5. 如果异步任务不是静态的,则可能会泄漏。我认为这不是问题,因为它还是很快完成的,对吧?

2 个答案:

答案 0 :(得分:0)

RecyclerView用于长列表,ViewHolder模式的实现通过在视图离开屏幕后重新使用视图来提高性能。如果您没有足够的项目来填充视口,则没有理由使用它。

还要记住,调试设置位图的速度要慢得多,如果可能,请尝试将其构建为“发布”并查看其性能。

答案 1 :(得分:0)

  1. 当您向下滚动时,您的ViewHolder将被重用,但是您至少需要足够的视图持有者来显示当前在屏幕上显示的内容,以及更多不在屏幕上显示的内容。因此,当您第一次加载时,屏幕上是否显示40个视图?如果没有,那么您有问题。
  2. 这取决于您是否可以滚动很多视图。
  3. 您可能会有所改善,但我对此表示怀疑。
  4. 共享的首选项调用被缓存。您无需担心它们在首次访问后会花费很长时间。
  5. 不确定

其他改进: 您可以将LayoutInflater的创建内容移至setUpAdapter()

R.layout.item_tab中有什么?确保视图层次尽可能平坦。如果可以,请使用约束布局。