在“冷启动”上长时间加载应用程序,并具有2个回收站视图

时间:2019-01-29 20:25:25

标签: java android android-recyclerview

我已经开始从头开始构建新应用,因此目前仅包含一个活动。此活动包含2个垂直的RecyclerView,第一个包含30个Button,然后以空格分隔RecyclerView,然后第二个RecyclerView,包含50个Button。每个RecyclerView都设置了GridLayoutManagerRecyclerView中的任何一个都不从数据库/网络中获取数据,它们具有固定的大小和数量。当我运行这段代码时,它会在约2秒内启动,logcat会以〜70-80的速率显示跳帧。 当我跳过设置布局时,它可以正常启动。 这是我的活动:

 private GridLayoutManager mLayoutManager, mSecondManager;
private RecyclerView mRecyclerViewFirst, mRecyclerViewSecond;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    rvAdapter firstAdapter = new rvAdapter();
    rvAdapter2 secondAdapter = new rvAdapter2();

    mRecyclerViewFirst = findViewById(R.id.recycler_view1);
    mRecyclerViewSecond = findViewById(R.id.recycler_view2);

    mRecyclerViewFirst.setNestedScrollingEnabled(false);
    mRecyclerViewSecond.setNestedScrollingEnabled(false);

    mRecyclerViewFirst.setAdapter(firstAdapter);
    mRecyclerViewSecond.setAdapter(secondAdapter);



}

@Override
protected void onResume() {
    super.onResume();

    int orientation = getResources().getConfiguration().orientation;
    if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
        mLayoutManager = new GridLayoutManager(getApplicationContext(), 8);
        mSecondManager = new GridLayoutManager(getApplicationContext(), 8);
    } else {
        mLayoutManager = new GridLayoutManager(getApplicationContext(), 5);
        mSecondManager = new GridLayoutManager(getApplicationContext(), 5);
    }

    mRecyclerViewFirst.setLayoutManager(mSecondManager);
    mRecyclerViewSecond.setLayoutManager(mLayoutManager);

}

一个适配器(第二个是相同的,只是计数不同):

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    return new ViewHolder(LayoutInflater.from(viewGroup.getContext().getApplicationContext())
            .inflate(R.layout.items_recyclerview, viewGroup, false));
}

@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    holder.mButton.setText(String.valueOf(position + 1));

}

@Override
public int getItemCount() {
    return 50;
}

class ViewHolder extends RecyclerView.ViewHolder {
    private Button mButton;

    private ViewHolder(@NonNull View view) {
        super(view);
        mButton = view.findViewById(R.id.button);
    }
}
}

布局:https://gitlab.com/Domin_PL/sample/blob/master/activity_main 在将XML代码添加到堆栈时遇到了麻烦

这是目前的整个应用程序,因此问题出在LayoutManager上。顺便说一句,在onResume中检测设备的方向不会造成这种滞后。

任何想法如何解决此滞后问题? 预先感谢

2 个答案:

答案 0 :(得分:0)

可能是您的xml文件出现问题。如果将 constraintlayout 用于 recyclerview 单元格,则滞后太多。因为主ui线程上的负载过多。避免在Recyclerview项目中进行约束布局。请共享您的recyclerview项目的xml文件。

答案 1 :(得分:0)

在冷启动该应用程序后,我设法将其平均降低了30〜35个跳帧。我使用了一个具有不同视图类型的RecyclerView和一个ViewHolder作为标题和按钮。这是我获得该结果的代码:

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRecyclerView = findViewById(R.id.recycler_view);
        mRecyclerView.setAdapter(new RvAdapter(
                ContextCompat.getColor(this, R.color.colorPrimaryDark),
                ContextCompat.getColor(this, R.color.white)
        ));
    }

    @Override
    protected void onResume() {
        super.onResume();

        final int orientation = getResources().getConfiguration().orientation;
        final int columnCount = orientation == Configuration.ORIENTATION_LANDSCAPE ? 8 : 5;
        final GridLayoutManager layoutManager = new GridLayoutManager(getApplicationContext(), columnCount);

        layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int i) {
                return (i == 0 || i == 31) ? columnCount : 1;
            }
        });

        mRecyclerView.setLayoutManager(layoutManager);
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

RvAdapter.java

public class RvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final int BUTTON_FIRST_GROUP_COUNT = 30;
    private static final int BUTTON_SECOND_GROUP_COUNT = 50;

    private static final int TYPE_TITLE = 0;
    private static final int TYPE_BUTTON = 1;

    @ColorInt
    private final int colorPrimary;
    @ColorInt
    private final int colorWhite;

    private String[] content = new String[BUTTON_FIRST_GROUP_COUNT + BUTTON_SECOND_GROUP_COUNT + 2 /* titles */];

    RvAdapter(@ColorInt final int colorPrimary, @ColorInt final int colorWhite) {
        this.colorPrimary = colorPrimary;
        this.colorWhite = colorWhite;

        initContent();
    }

    private void initContent() {
        for (int i = 0; i < content.length; i++) {
            final String prefix = isTitle(i) ? "Title " : "";
            content[i] = prefix + (i + 1);
        }
    }

    private boolean isTitle(final int position) {
        return (position == 0 || position == BUTTON_FIRST_GROUP_COUNT + 1);
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        final LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());

        if (viewType == TYPE_TITLE) {
            return new TitleViewHolder(layoutInflater.inflate(R.layout.item_title, viewGroup, false));
        }
        return new ButtonViewHolder(layoutInflater.inflate(R.layout.item_button, viewGroup, false));
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        final String currentContent = content[position];

        if (holder instanceof TitleViewHolder) {
            final TitleViewHolder titleViewHolder = (TitleViewHolder) holder;
            titleViewHolder.mTextView.setText(currentContent);
        } else {
            final ButtonViewHolder buttonViewHolder = (ButtonViewHolder) holder;

            buttonViewHolder.setBackgroundColor(position <= BUTTON_FIRST_GROUP_COUNT ? colorPrimary : colorWhite);
            buttonViewHolder.mButton.setText(currentContent);
        }

    }

    @Override
    public int getItemViewType(int position) {
        return isTitle(position) ? TYPE_TITLE : TYPE_BUTTON;
    }

    @Override
    public int getItemCount() {
        return content.length;
    }
}

希望它会为您提供帮助。