当前位置: 首页 > 知识库问答 >
问题:

如何在保持高性能的同时布局嵌套的RecyclerViews?

任绪
2023-03-14

我正在尝试实现类似于Google Play Music的“立即收听”布局。我在网上找到的每一个例子都是一个简单的回收视图。我正在努力实现更复杂的目标。差不多

整个布局(减去工具栏)是否可以是一个包含两个或多个RecyclerView的RecyclerViews?差不多

最终,我想要实现的是一个如下的布局,并保持良好的性能

<RecyclerView> //vertical
    <RecyclerView/> //vertical
    <RecyclerView/> //horizontal
    <LinearLayout/> //horizontal
</RecyclerView>

共有2个答案

钱旻
2023-03-14

我试图解决在垂直回收器视图中有水平回收器视图的情况,这是我的代码

单片段活动

package com.example.uitestingmaterialdesign;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;


public abstract class SingleFragmentActivity extends AppCompatActivity {

protected abstract Fragment createFragment();

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

    FragmentManager fm = getSupportFragmentManager();
    Fragment fragment = fm.findFragmentById(R.id.simple_fragment_container);

    if (fragment == null) {
        fragment = createFragment();
        fm.beginTransaction()
                .add(R.id.simple_fragment_container, fragment)
                .commit();
    }
}

}

主要活动

package com.example.uitestingmaterialdesign;

import android.support.v4.app.Fragment;

public class MainActivity extends SingleFragmentActivity {

@Override
protected Fragment createFragment() {
    return new PrimaryRecyclerViewFragment();
}

}

PrimaryRecyclerView

package com.example.uitestingmaterialdesign;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


public class PrimaryRecyclerViewFragment extends Fragment {

private RecyclerView mPrimaryRecyclerView;
private String[] mMoviesGenre, mActionMovies;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mMoviesGenre = new String[]{
            "Action", "Adventure", "Comedy", "Crime", "Fantasy",
            "Historical", "Horror", "Magical", "Mystery", "Paranoid"
    };

    mActionMovies = new String[] {"Mission: Impossible – Rogue Nation", 
            "Mad Max: Fury Road", "Star Wars: The Force Awakens",
            "Avengers: Age of Ultron", "Ant- Man","Terminator Genisys",        "Furious 7",              "Blackhat", "The Man from U.N.C.L.E",
            "Jurassic World"
    };

}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.primary_recycler_view, container, false);

    // Creating the primary recycler view adapter
    PrimaryAdapter adapter = new PrimaryAdapter(mMoviesGenre);

    LinearLayoutManager layoutManager = new LinearLayoutManager(
            getActivity(),
            LinearLayoutManager.VERTICAL,
            false
    );

    mPrimaryRecyclerView = (RecyclerView) view.findViewById(R.id.primary_recycler_view);
    mPrimaryRecyclerView.setLayoutManager(layoutManager);
    mPrimaryRecyclerView.setAdapter(adapter);

    return view;
}

private class PrimaryViewHolder extends RecyclerView.ViewHolder {
    private TextView mPrimaryMovieGenre;
    private RecyclerView mSecondaryRecyclerView;

    public PrimaryViewHolder(View itemView) {
        super(itemView);
        mPrimaryMovieGenre = (TextView) itemView.findViewById(R.id.primary_movie_genre);
        mSecondaryRecyclerView = (RecyclerView) itemView.findViewById(R.id.secondary_recycler_view);
    }

    // This get called in PrimaryAdapter onBindViewHolder method
    public void bindViews(String genre, int position) {
        mPrimaryMovieGenre.setText(genre);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
                getActivity(),
                LinearLayoutManager.HORIZONTAL,
                false
        );

        mSecondaryRecyclerView.setLayoutManager(linearLayoutManager);
        mSecondaryRecyclerView.setAdapter(getSecondaryAdapter(position));
    }
}

private class PrimaryAdapter extends RecyclerView.Adapter<PrimaryViewHolder> {
    private String[] mMovieGenre;

    public PrimaryAdapter(String[] moviesGenre) {
        mMovieGenre = moviesGenre;
    }

    @Override
    public PrimaryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(getActivity());
        View view = inflater.inflate(R.layout.primary_recycler_view_item, parent, false);
        return new PrimaryViewHolder(view);
    }

    @Override
    public void onBindViewHolder(PrimaryViewHolder holder, int position) {
        String genre = mMovieGenre[position];
        holder.bindViews(genre, position);
    }

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

private class SecondaryViewHolder extends RecyclerView.ViewHolder {

    private TextView mTextView;

    public SecondaryViewHolder(View view) {
        super(view);
        mTextView = (TextView) itemView.findViewById(R.id.secondary_text_view);
    }

    public void bindView(String name) {
        mTextView.setText(name);
    }
}

private class SecondaryAdapter extends RecyclerView.Adapter<SecondaryViewHolder> {
    private String[] mMovies;

    public SecondaryAdapter(String[] movies) {
        mMovies = movies;
    }

    @Override
    public SecondaryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(getActivity());
        View view = inflater.inflate(R.layout.secondary_recycler_view_item, parent, false);
        return new SecondaryViewHolder(view);
    }

    @Override
    public void onBindViewHolder(SecondaryViewHolder holder, int position) {
        String name = mMovies[position];
        holder.bindView(name);
    }

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

private SecondaryAdapter getSecondaryAdapter(int position) {

    SecondaryAdapter adapter;
    switch (position) {
        case 0:
            return new SecondaryAdapter(mActionMovies);
        case 1:
            return null;
        case 2:
            return null;
        case 3:
            return null;
        case 4:
            return null;
        case 5:
            return null;
        case 6:
            return null;
        case 7:
            return null;
        case 8:
            return null;
        case 9:
            return null;
        default:
            return null;
    }
}
}

Primary_recycler_view.xml

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

primary_recycler_view_item。xml(具有水平回收器视图)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card_view:cardCornerRadius="4dp"
    card_view:cardElevation="2dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="8dp"
        android:layout_gravity="bottom">

        <TextView
            android:id="@+id/primary_movie_genre"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:paddingTop="16dp"
            android:paddingBottom="16dp"/>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/secondary_recycler_view"
            android:layout_gravity="center_horizontal"
            android:layout_width="360dp"
            android:layout_height="180dp"/>
    </LinearLayout>

</android.support.v7.widget.CardView>

</LinearLayout>

secondary_recycler_view_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:gravity="center">

<TextView
    android:id="@+id/secondary_text_view"
    android:layout_width="120dp"
    android:layout_height="160dp"
    android:gravity="center|bottom"
    android:background="#BDBDBD"/>
</LinearLayout>

single_fragment_activity

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

如果您有任何疑问或找到了更好的方法,请告知,我希望这有帮助。

司徒泰
2023-03-14

您不能将 recyclerview 放在 recyclerview 标签中。相反,在你的第一个适配器的 bindViewHolder 调用再次 recyclerview 适配器,如:-

InnerRecyclerviewAdapter adapter=new InnerRecyclerviewAdapter(context,urlistArray);
holder.recyclerView.setAdapter(adapter);
holder.recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(layoutManager);

wrap_content也将与最新的回收器视图一起使用

欲了解更多信息,请查看此链接https://guides.codepath.com/android/Heterogenous-Layouts-inside-RecyclerView

 类似资料:
  • 问题内容: 我试图组成一个简单的API客户端,但我一直试图弄清楚如何使其可读性和可测试性。如何在保持可测试性的同时组成嵌套结构? 伪代码: 现在,我可以像这样调用API: 这给我提供了一个非常可读(嵌套)的实现,但是我很难模拟这些端点,因为使用接口会有效地消除对嵌套结构的任何识别。推荐一种构造API的方法,以保持其可读性,同时模拟每个端点? 问题答案: 您正在与语言作斗争,并将您的OOP爱好带入并

  • 我正在使用浏览器。我为寻呼机适配器制作了一个XML(我有4页寻呼机),在这个XML中,我只使用了多个线性布局,并将它们的可见性设置为消失。默认情况下,第一个线性布局的可见性是打开的,所以它可以很容易地设置为页面的第一页。现在,我正在尝试的是,当我滚动页面时,第一个线性布局的可见性应该消失,第二个线性布局的可见性应该打开(相同的XML ),并设置为页面,等等。 这是我的xml(适配器) 这是我的<

  • 我正在尝试添加具有线性布局的背景图像作为根布局[Look hierarchy diagram for reference.]我曾尝试使用相对布局作为根布局,但它与嵌套的线性布局重叠。当线性布局作为根布局时,它只显示在底部。 XML代码 查看层次结构图

  • 我在<code>androidx.compose.ui.layout.SubcomposeLayout的源代码中看到了这个函数。kt在androidx.compose.ui中:ui:1.0.0-beta02。 当composable将在subcomposable中呈现时,看起来我不能使用内部度量。 作为参考,我试图在ModalBottomSheet中使用这样的视图。目的是在工作表中具有可滚动的视图

  • 我有这张单子: 我希望将每个列表中的字符串元素连接在一起,同时保持列表结构。 预期的行为如下所示: 它将与此非常相似,但它必须能够处理任意数量的嵌套列表。 我试图用一个递归函数来解决它,但没有得到预期的结果。 有什么提示吗?

  • 我正在使用AWS Lambda、API网关和CloudFormation开发REST API。我达到了Cloudformation 500资源限制,因此我不得不选择嵌套堆栈。下面是我试过的。 样板亚马尔 模板用户。亚马尔 模板2。亚马尔 这是可行的,但我注意到API网关为我创建的每个堆栈分配了不同的URL。在这个例子中,我有两个堆栈,API网关创建了两个URL。 URL-https://ez5kh