简体   繁体   English

如何在RecyclerView中展开和折叠卡片?

[英]How to expand and collapse cards in RecyclerView?

I have gone through 20-30 links on internet but none of them was helpful as every code has certain limitations. 我已经遍历了Internet上的20-30个链接,但由于每个代码都有一定的局限性,所以它们都不会有帮助。 I have cards in a RelativeLayout in RecyclerView which i want to expand on clicking the Details button. 我在RecyclerView的RelativeLayout中有卡片,要在单击“详细信息”按钮时对其进行扩展。 CardViews have simply textViews and Buttons inside them NOT Lists. CardViews内部仅具有textViews和Buttons NOT Lists。 Please have a look at my code and help me in how can i achieve this. 请查看我的代码,并帮助我如何实现这一目标。

activity_phrase_search.xml : activity_phrase_search.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_phrase_search"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="in.hkcl.pdfsearcher.PhraseSearchActivity"
    android:background="#EEEEEE">

    <include android:id="@+id/toolbar"
        layout="@layout/toolbar_layout"></include>

    <EditText
        android:id="@+id/inputSearchPhrase"
        android:layout_below="@id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:gravity="center_vertical"
        android:maxLines="1"
        android:padding="5dp"
        android:textColor="#004D40"
        android:inputType="text"
        android:ellipsize="end"
        android:scrollHorizontally="true"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/search_edittext"
        android:ems="10"
        android:hint="Search your phrase here ..."
        android:drawableLeft="@drawable/search"
        android:drawableRight="@drawable/deletetext"
        android:drawablePadding="12dp"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclrviewPhrase"
        android:layout_marginTop="8dp"
        android:layout_below="@id/inputSearchPhrase"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:behavior_overlapTop="14dp" />

component_phrase_list.xml : component_phrase_list.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="#9E9E9E"
    android:clickable="true"
    android:focusable="true"
    android:paddingBottom="4dp"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"
    android:paddingTop="8dp"
    >
    <android.support.v7.widget.CardView
        android:id="@+id/outerBoundaryCard"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_gravity="center"
        android:elevation="4dp"
        android:background="?android:attr/selectableItemBackground">
        <RelativeLayout
            android:id="@+id/visible_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:padding="10dp">
    <TextView
        android:id="@+id/documentName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:gravity="center_vertical"
        android:textStyle="bold"/>

    <Button
        android:id="@+id/details_btn"
        android:layout_below="@id/documentName"
        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:layout_alignParentRight="true"
        android:layout_marginTop="5dp"
        android:text="Details"
        android:textColor="#FFFFFF"
        android:background="#FBCC38"
        android:textStyle="bold"/>

    <ImageButton
        android:id="@+id/link_btn"
        android:layout_below="@id/documentName"
        android:src="@drawable/link"
        android:layout_toLeftOf="@id/details_btn"
        android:layout_marginTop="5dp"
        android:layout_marginRight="10dp"
        android:layout_width="50dp"
        android:layout_height="40dp"
        android:background="#FFFFFF"/>

        </RelativeLayout>

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

    <LinearLayout
        android:id="@+id/hidden_layout"
        android:layout_below="@id/outerBoundaryCard"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    <TextView
        android:id="@+id/expanded_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone"/>
    </LinearLayout>

    <View
        android:id="@+id/hr"
        android:layout_below="@id/hidden_layout"
        android:layout_marginTop="5dp"
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#FFFFFF"></View>

</RelativeLayout>

RecyclerViewAdapterPhraseList.java : RecyclerViewAdapterPhraseList.java:

package in.hkcl.pdfsearcher;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.transition.TransitionManager;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

/**
 * Created by Android on 11/17/2017.
 */

public class RecyclerViewAdapterPhraseList extends RecyclerView.Adapter<RecyclerViewAdapterPhraseList.PhraseListHolder> {

    private ArrayList<PhraseModel.PhraseList> mPhraseList;
    public  boolean isExpanded=false;


    public class PhraseListHolder extends RecyclerView.ViewHolder {
        TextView documentName,expanded_text;
        Button detailsBtn;
        ImageButton linkBtn;
        LinearLayout hidden_layout;

        /*RelativeLayout expandable_view;*/

        public PhraseListHolder(View itemView) {
            super(itemView);
            documentName=(TextView)itemView.findViewById(R.id.documentName);
            detailsBtn=(Button)itemView.findViewById(R.id.details_btn);
            linkBtn=(ImageButton)itemView.findViewById(R.id.link_btn);
            expanded_text=(TextView)itemView.findViewById(R.id.expanded_text);
            hidden_layout=(LinearLayout)itemView.findViewById(R.id.hidden_layout);
            /*expandable_view=(RelativeLayout)itemView.findViewById(R.id.expandable_view);*/
        }
    }

    public RecyclerViewAdapterPhraseList(ArrayList<PhraseModel.PhraseList> mPhraseList) {
        this.mPhraseList = mPhraseList;
    }

    @Override
    public RecyclerViewAdapterPhraseList.PhraseListHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.component_phrase_list,parent,false);
        PhraseListHolder phraseListHolder=new PhraseListHolder(view);
        return phraseListHolder;
    }

    @Override
    public void onBindViewHolder(final RecyclerViewAdapterPhraseList.PhraseListHolder holder, final int position) {
        String documentNameWithoutUrl=mPhraseList.get(position).documentName;

        holder.documentName.setText(documentNameWithoutUrl.substring(documentNameWithoutUrl.lastIndexOf('/')+1, documentNameWithoutUrl.length()));
        holder.linkBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse(mPhraseList.get(position).getDocumentName()));
                v.getContext().startActivity(i);

            }
        });

        holder.detailsBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*Intent j = new Intent (v.getContext(), OccurenceDetailsActivity.class);
                j.putParcelableArrayListExtra("occurences",mPhraseList.get(position).getOccurenceDetails());
                v.getContext().startActivity(j);*/
                holder.expanded_text.setVisibility(View.VISIBLE);
                holder.expanded_text.setEnabled(true);
                holder.expanded_text.setText(mPhraseList.get(position).getNoOfOccurences());

            }
        });
    }

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

Earlier links on stackoverflow are not according to my code so i am facing a lot of issues in implementing them. 关于stackoverflow的早期链接并不符合我的代码,因此在实现它们时我面临很多问题。 Plz help how can i do this? 请帮助我如何做到这一点?

In my opinion, the expansion and collapsing of the Card can be be done by animating the height of the TextView with the id expanded_text instead of just toggling the visibility. 在我看来,扩展和卡的崩溃可以通过动画TextView的高度与ID expanded_text而不只是切换的知名度来完成。

The implementation of the expanding/collapsing animation can be done in the following manner: 展开/折叠动画的实现可以通过以下方式完成:

holder.detailsBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            /*Intent j = new Intent (v.getContext(), OccurenceDetailsActivity.class);
            j.putParcelableArrayListExtra("occurences",mPhraseList.get(position).getOccurenceDetails());
            v.getContext().startActivity(j);*/


            holder.expanded_text.setText(mPhraseList.get(position).getNoOfOccurences());

            // Object Animator to animate the expanded_text TextView 
            ObjectAnimator scaleHeightAnim;

            // Checking if the TextView is already visible, if "yes", 
            //animating and collapsing the TextView, else expanding the TextView. 
            if (expanded_text.getVisibility() == View.VISIBLE) {

                AnimatorSet animatorSet = new AnimatorSet();

                scaleHeightAnim = ObjectAnimator.ofFloat(expanded_text, "height", expanded_text.getHeight(), 0);

                animatorSet.play(scaleHeightAnim);
                animatorSet.setDuration(1000);
                animatorSet.start();

                animatorSet.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        expanded_text.setVisibility(View.GONE);
                    }
                });

            } else {

                AnimatorSet animatorSet = new AnimatorSet();

                expanded_text.setVisibility(View.VISIBLE);
                scaleHeightAnim = ObjectAnimator.ofFloat(expanded_text, "height", 0, expanded_text.getHeight());

                animatorSet.play(scaleHeightAnim);
                animatorSet.setDuration(1000);
                animatorSet.start();
            }

        }
    });

I hope this tip helps you add soft animation effect to the expansion/collapse of the details text in the CardView. 希望本技巧可以帮助您为CardView中的详细信息文本的扩展/折叠添加柔和的动画效果。 Let me know if there are any concerns. 让我知道是否有任何问题。

Thank you. 谢谢。 :) :)

I have made some changes in your layout and adapter 我对您的布局和适配器进行了一些更改

// here is your hidden layout //这是您的隐藏布局

<LinearLayout
        android:id="@+id/hidden_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/outerBoundaryCard"
        android:background="@color/colorPrimaryDark"
        android:orientation="vertical"
        android:visibility="gone">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/expanded_text"
            />
    </LinearLayout>

// here is your viewholder //这是您的观看者

public class PhraseListHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView documentName, expanded_text;
    Button detailsBtn;
    ImageButton linkBtn;
    LinearLayout hidden_layout;

    /*RelativeLayout expandable_view;*/

    public PhraseListHolder(View itemView) {
        super(itemView);
        documentName = itemView.findViewById(R.id.documentName);
        detailsBtn = itemView.findViewById(R.id.details_btn);
        linkBtn =  itemView.findViewById(R.id.link_btn);
        expanded_text = itemView.findViewById(R.id.expanded_text);
        hidden_layout = itemView.findViewById(R.id.hidden_layout);

        detailsBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        hidden_layout.setVisibility(View.VISIBLE);
        hidden_layout.setEnabled(true);
     expanded_text.setText(mPhraseList.get(getAdapterPosition()).getNoOfOccurences());
    }
}

tell me if it solves your problem 告诉我是否可以解决您的问题

Your code is working fine, you already have expansion code on your detailsBtn click. 您的代码运行良好,您的详细信息上已经有扩展代码。 Just check for the value of "mPhraseList.get(position).getNoOfOccurences()" for empty, I think it gives you empty string. 只需检查“ mPhraseList.get(position).getNoOfOccurences()”的值是否为空,我认为它会为您提供空字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM