具有多个Recycler Views的片段冻结了UI

时间:2018-05-10 13:18:41

标签: android performance android-fragments android-recyclerview recycler-adapter

我正在创建一个Fragment,它在垂直Scroll视图下有5个水平回收视图,但每次需要加载这个片段时,UI会冻结大约一秒钟。

我创建了一个Adapter,它将来自2个不同POJO的数据设置为不同的Recycler Views。我发现我的代码中似乎导致问题的那一行是setLayoutManager()因为一旦注释,片段加载不会冻结UI。除此之外,我还没有找到为什么在将LayoutManger分配给回收器视图时发生这种情况,以及我该怎么做才能提高片段的性能。

这是fragment_home.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.entertainment.logicaldays.planetmovie.views.fragments.HomeFragment"
    android:id="@+id/layout"
    android:background="@color/colorPrimary">
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/scroll_view">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
                <android.support.v4.view.ViewPager
                    android:layout_width="match_parent"
                    android:layout_height="200dp"
                    android:id="@+id/view_pager"
                    android:layout_marginBottom="5dp">
                </android.support.v4.view.ViewPager>
                <android.support.v7.widget.RecyclerView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/recycler_popular_movies"
                    android:orientation="horizontal">
                </android.support.v7.widget.RecyclerView>
                <android.support.v7.widget.RecyclerView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/recycler_upcoming_movies"
                    android:orientation="horizontal">
                </android.support.v7.widget.RecyclerView>
                <android.support.v7.widget.RecyclerView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/recycler_top_rated_movies"
                    android:orientation="horizontal">
                </android.support.v7.widget.RecyclerView>
                <android.support.v7.widget.RecyclerView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/recycler_popular_tv_shows"
                    android:orientation="horizontal">
                </android.support.v7.widget.RecyclerView>
                <android.support.v7.widget.RecyclerView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/recycler_top_rated_tv_shows"
                    android:orientation="horizontal">
                </android.support.v7.widget.RecyclerView>
        </LinearLayout>
    </ScrollView>
</FrameLayout>

然后我将recycler_item.xml绑定到Recycler Views:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dp">
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_gravity="center">
                <RelativeLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/hover_values">
                        <ImageView
                            android:layout_width="wrap_content"
                            android:layout_height="150dp"
                            android:src="@drawable/ic_launcher_background"
                            android:layout_gravity="center|top"
                            android:id="@+id/recycler_image" />
                        <ImageView
                            android:layout_width="20dp"
                            android:layout_height="20dp"
                            android:layout_alignParentTop="true"
                            android:layout_marginTop="20dp"
                            android:alpha="0"
                            android:id="@+id/poster_hover_image"
                            android:layout_centerHorizontal="true"
                            android:src="@drawable/star"/>
                        <TextView
                            android:layout_marginTop="5dp"
                            android:alpha="0"
                            android:id="@+id/poster_hover_text"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_below="@id/poster_hover_image"
                            android:fontFamily="@font/theboldfont"
                            android:layout_centerHorizontal="true" />
                </RelativeLayout>
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textAlignment="center"
                    android:scrollHorizontally="true"
                    android:minLines="2"
                    android:maxLines="2"
                    android:ellipsize="end"
                    android:id="@+id/recycler_title"/>
        </LinearLayout>
</LinearLayout>

适配器可以将2个不同的POJO绑定到Recycler Views:

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

    public Object pojo;
    public Context context;

    public RecyclerViewAdapter(Context ctx, Object movies) {
        this.pojo = movies;
        this.context = ctx;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);

        final ValueAnimator animatorPosterTint = ValueAnimator.ofInt(0, 180);
        final ValueAnimator animatorHoverOpacity = ValueAnimator.ofFloat(0, 1);

        //When long-pressing the Movie
        view.setOnLongClickListener(new LongClickOnPosterItemListerner(view, animatorPosterTint, animatorHoverOpacity));

        //When releasing the touch on the movie
        view.setOnTouchListener(new ReleasePosterItemListener(view, animatorPosterTint, animatorHoverOpacity));

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        if(pojo instanceof MovieList) {
            holder.title.setText(((MovieList)pojo).results.get(position).title);
            Glide.with(context)
                    .asBitmap()
                    .load(Utils.BASE_TMDB_POSTER_URL + ((MovieList)pojo).results.get(position).posterPath)
                    .into(holder.image);
            holder.rating.setText(Float.toString(((MovieList)pojo).results.get(position).voteAverage));
        }
        else{
            holder.title.setText(((TVList)pojo).results.get(position).name);
            Glide.with(context)
                    .asBitmap()
                    .load(Utils.BASE_TMDB_POSTER_URL + ((TVList)pojo).results.get(position).posterPath)
                    .into(holder.image);
            holder.rating.setText(Float.toString(((TVList)pojo).results.get(position).voteAverage));
        }
    }

    @Override
    public int getItemCount() {
        int count = 0;

        if(pojo instanceof MovieList && ((MovieList)pojo).results != null) {
            if (((MovieList)pojo).results != null) {
                count = ((MovieList)pojo).results.size();
            }
        }
        else{
            if (((TVList)pojo).results != null) {
                count = ((TVList)pojo).results.size();
            }
        }

        return count;
    }

    public class ViewHolder extends RecyclerView.ViewHolder{
        ImageView image;
        TextView title;
        TextView rating;

        public ViewHolder(View itemView) {
            super(itemView);
            image = itemView.findViewById(R.id.recycler_image);
            title = itemView.findViewById(R.id.recycler_title);
            rating = itemView.findViewById(R.id.poster_hover_text);
        }
    }
}

最后我们有了HomeFragment.java

public class HomeFragment extends Fragment {
    public MainActivity mainActivity;

    @BindView(R.id.recycler_popular_movies)
    RecyclerView recyclerPopularMovies;

    @BindView(R.id.recycler_upcoming_movies)
    RecyclerView recyclerUpcomingMovies;

    @BindView(R.id.recycler_top_rated_movies)
    RecyclerView recyclerTopRatedMovies;

    @BindView(R.id.recycler_popular_tv_shows)
    RecyclerView recyclerPopularTVShows;

    @BindView(R.id.recycler_top_rated_tv_shows)
    RecyclerView recyclerTopRatedTVShows;

    @BindView(R.id.view_pager)
    ViewPager viewPager;

    LinkedHashMap<Utils.RequestsToLoad, Boolean> requestsToLoad;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        mainActivity = (MainActivity) getActivity();

        // Inflate the layout into the Fragment
        View v = inflater.inflate(R.layout.fragment_home, container, false);

        ButterKnife.bind(this, v);

        startViewPager();
        startRecyclerViews();

        return v;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }

    private void startRecyclerViews(){
        displayRecyclerView(recyclerPopularMovies, mainActivity.popularMovies);
        displayRecyclerView(recyclerTopRatedMovies, mainActivity.upcomingMovies);
        displayRecyclerView(recyclerUpcomingMovies, mainActivity.topRatedMovies);
        displayRecyclerView(recyclerPopularTVShows, mainActivity.popularTVShow);
        displayRecyclerView(recyclerTopRatedTVShows, mainActivity.topRatedTVShow);
    }

    private void displayRecyclerView(RecyclerView recyclerView, Object object){
        LinearLayoutManager layoutManager = new LinearLayoutManager(mainActivity, LinearLayoutManager.HORIZONTAL, false);
        final RecyclerViewAdapter adapter = new RecyclerViewAdapter(getActivity(), object);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(layoutManager);
    }

    private void startViewPager(){
        SwipeAdapter swipeAdapter = new SwipeAdapter(getActivity(), mainActivity.upcomingMovies);
        viewPager.setAdapter(swipeAdapter);
    }

}

如前所述,是否有任何可能导致延迟加载片段以便我可以改进它?

提前致谢

0 个答案:

没有答案