代码之家  ›  专栏  ›  技术社区  ›  Javad Karbasian

如何制作可扩展的卡片视图列表?

  •  8
  • Javad Karbasian  · 技术社区  · 9 年前

    我搜索了很多,想找到一个直接而清晰的解决方案,因为我认为这是一个很受欢迎的问题,但不幸的是我找不到它。

    我们希望有一个卡片视图列表,这样每张卡片都绑定到一个特定的数据,并且每张卡片内部都有一个列表,显示关于其父卡片的元数据或详细数据。

    所以我们在cardview中有一个嵌套列表。

    通过简单的搜索,我们知道应该使用扩展列表视图,其中父项是卡片视图,并且必须为其子项设置另一个布局。

    所以当你点击卡片时,一个项目列表会出现在你的卡片下面的根上。 但我们想在卡片里面显示儿童列表吗?

    因此,明确的问题是如何在cardview中添加列表视图?

    我使用tablelayout和tablerow来完成我的工作。并且不喜欢使用外部库来解决稳定性和版本问题。 这就是我的意思。

    描述我问题的图像

    image that describe my question

    2 回复  |  直到 9 年前
        1
  •  23
  •   Thomas Mary GraSim    6 年前

    如果您不想使用外部库,您可以让CardView按如下方式展开:

    可扩展CardView的布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/cv"
    android:layout_marginTop="5dp"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    card_view:cardCornerRadius="5dp">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:orientation="vertical">
    
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="48dp"
                >
    
                <TextView
                    android:id="@+id/textView_name"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp"
                    android:textSize="18sp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textStyle="bold" />
    
                <!--My dropdown Button -->
                <RelativeLayout
                    android:id="@+id/button"
                    android:layout_width="48dp"
                    android:layout_height="48dp"
                    android:layout_gravity="end"
                    android:layout_alignParentRight="true"
                    android:gravity="center"
                    >
    
                    <View
                        android:layout_width="12dp"
                        android:layout_height="12dp"
                        android:background="@drawable/triangle"
                        android:layout_alignParentRight="false"
                        android:layout_alignParentEnd="false" />
                </RelativeLayout>
            </RelativeLayout>
             <!--The layout below is my ExpandableLayout -->
            <LinearLayout
                android:id="@+id/expandableLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                >
    
                <android.support.v7.widget.AppCompatImageView
                    android:id="@+id/imageView_Owner"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
    
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="5dp"
                    android:orientation="vertical">
    
                    <TextView
                        android:id="@+id/textView_Owner"
                        android:textSize="16sp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content" />
                    <TextView
                        android:id="@+id/textView_OwnerUrl"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content" />
    
    
                </LinearLayout>
    
            </LinearLayout>
    
        </LinearLayout>
    
    </android.support.v7.widget.CardView>
    

    我的ExpandableRecyclerAdapter类

    import android.animation.ObjectAnimator;
    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.util.SparseBooleanArray;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.animation.LinearInterpolator;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    
    import com.squareup.picasso.Picasso;
    import java.util.List;
    
    
    public class ExpandableRecyclerAdapter extends RecyclerView.Adapter<ExpandableRecyclerAdapter.ViewHolder> {
    
    private List<Repo> repos;
    private SparseBooleanArray expandState = new SparseBooleanArray();
    private Context context;
    
    public ExpandableRecyclerAdapter(List<Repo> repos) {
        this.repos = repos;
        //set initial expanded state to false
        for (int i = 0; i < repos.size(); i++) {
            expandState.append(i, false);
        }
    }
    
    @Override
    public ExpandableRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        this.context = viewGroup.getContext();
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.expandable_card_row, viewGroup, false);
        return new ViewHolder(view);
    }
    
    @Override
    public void onBindViewHolder(final ExpandableRecyclerAdapter.ViewHolder viewHolder, final  int i) {
    
        viewHolder.setIsRecyclable(false);
    
        viewHolder.tvName.setText(repos.get(i).getName());
    
        viewHolder.tvOwnerLogin.setText("Owner: " +repos.get(i).getOwner().getLogin());
        viewHolder.tvOwnerUrl.setText(repos.get(i).getOwner().getUrl());
    
        Picasso.with(context)
                .load(repos.get(i).getOwner().getImageUrl())
                .resize(500, 500)
                .centerCrop()
                .into(viewHolder.ivOwner);
    
        //check if view is expanded
        final boolean isExpanded = expandState.get(i);
        viewHolder.expandableLayout.setVisibility(isExpanded?View.VISIBLE:View.GONE);
    
        viewHolder.buttonLayout.setRotation(expandState.get(i) ? 180f : 0f);
        viewHolder.buttonLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
                onClickButton(viewHolder.expandableLayout, viewHolder.buttonLayout,  i);
            }
        });
    }
    
    @Override
    public int getItemCount() {
        return repos.size();
    }
    
    public class ViewHolder extends RecyclerView.ViewHolder{
    
        private TextView tvName,tvOwnerLogin, tvOwnerUrl;
        private ImageView ivOwner;
        public RelativeLayout buttonLayout;
        public LinearLayout expandableLayout;
    
        public ViewHolder(View view) {
            super(view);
    
            tvName = (TextView)view.findViewById(R.id.textView_name);
            tvId = (TextView)view.findViewById(R.id.textView_id);
            tvUrl = (TextView)view.findViewById(R.id.textView_url);
            tvOwnerLogin = (TextView)view.findViewById(R.id.textView_Owner);
            tvOwnerUrl = (TextView)view.findViewById(R.id.textView_OwnerUrl);
            ivOwner = (ImageView) view.findViewById(R.id.imageView_Owner);
    
            buttonLayout = (RelativeLayout) view.findViewById(R.id.button);
            expandableLayout = (LinearLayout) view.findViewById(R.id.expandableLayout);
        }
    }
    
    private void onClickButton(final LinearLayout expandableLayout, final RelativeLayout buttonLayout, final  int i) {
    
        //Simply set View to Gone if not expanded
        //Not necessary but I put simple rotation on button layout
        if (expandableLayout.getVisibility() == View.VISIBLE){
            createRotateAnimator(buttonLayout, 180f, 0f).start();
            expandableLayout.setVisibility(View.GONE);
            expandState.put(i, false);
        }else{
            createRotateAnimator(buttonLayout, 0f, 180f).start();
            expandableLayout.setVisibility(View.VISIBLE);
            expandState.put(i, true);
        }
    }
    
    //Code to rotate button
    private ObjectAnimator createRotateAnimator(final View target, final float from, final float to) {
        ObjectAnimator animator = ObjectAnimator.ofFloat(target, "rotation", from, to);
        animator.setDuration(300);
        animator.setInterpolator(new LinearInterpolator());
        return animator;
    }
    }
    

    在Activity/Fragment中,按如下方式设置RecyclerView

    private RecyclerView recyclerView;
    private List<Repo> data;
    
    recyclerView = (RecyclerView)findViewById(R.id.card_recycler_view);
    recyclerView.setHasFixedSize(true);
    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
    recyclerView.setLayoutManager(layoutManager);
    //fetch data and on ExpandableRecyclerAdapter
    recyclerView.setAdapter(new ExpandableRecyclerAdapter(data));
    

    因此,在没有外部库的情况下创建可扩展的CardView非常简单。代码与使用普通CardView和RecyclerView几乎完全相同,主要的变化是设置View.GONE/View。点击按钮时可见。

        2
  •  0
  •   Aditya Vyas-Lakhan user1796260    9 年前

    你可以使用 ExpandLayout ,然后将其添加到 cardview .

    <com.kyo.expandablelayout.ExpandableLayout
            android:id="@+id/expandlayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="12dp" >
    
            <ImageView
                android:id="@+id/imageview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:contentDescription="@null"
                android:scaleType="centerCrop"
                android:src="@drawable/parent" />
    
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="6dp"
                android:contentDescription="@null"
                android:scaleType="centerCrop"
                android:src="@drawable/child"
                app:canExpand="true" />
        </com.kyo.expandable.ExpandableLayout>