রিসাইক্লারভিউ আইটেমগুলি প্রসারিত / পতন করুন


145

আরও তথ্য দেখানোর জন্য আমি আমার পুনর্ব্যবহারযোগ্য আইটেমগুলিকে প্রসারিত / ধস করতে চাই। আমি স্লাইডএক্সপ্যান্ডেবললিস্টভিউয়ের একই প্রভাব অর্জন করতে চাই

মূলত আমার ভিউহোল্ডারটিতে আমার একটি দৃশ্য আছে যা দৃশ্যমান নয় এবং আমি কেবল ভিজিবল / গনে দৃশ্যমানতা সেট করার পরিবর্তে একটি মসৃণ প্রসার / পতন অ্যানিমেশনটি করতে চাই। আমার কেবলমাত্র একবারে প্রসারিত করার জন্য একটি আইটেম প্রয়োজন এবং আইটেমটি নির্বাচিত হয়েছে তা দেখানোর জন্য কিছুটা উচ্চতা দেওয়া ভাল।

এটি নতুন অ্যান্ড্রয়েড সাম্প্রতিক কল ইতিহাসের তালিকার একই প্রভাব। "কল কল" এবং "DETAILS" বিকল্পগুলি কেবল তখনই প্রদর্শিত হবে যখন কোনও আইটেম নির্বাচন করা হবে।

পুনর্ব্যবহারযোগ্য সম্প্রসারণযোগ্য আইটেম


আমার একটি সম্পর্কিত প্রশ্ন আছে ক্লক অ্যাপে, অ্যালার্ম সেট ক্রিয়াকলাপে একই বৈশিষ্ট্য রয়েছে। এটি কি একইভাবে করা হয়?
ব্যবহারকারী 2731584

আরে সমাধান পেয়েছেন? আমি আমার অ্যাপ্লিকেশনটির জন্যও একই সমাধান খুঁজছি।
অর্পিত প্যাটেল

আপনি কি কোনও সমাধান খুঁজে পেয়েছেন?
আরমিন ঘোরিশি

1
আমি গুগল আই / ও ২০১
হাইজেনবার্গ

আমার উত্তরটি এখানে একটি সহজ এবং শীতল সমাধান দেখুন stackoverflow.com/a/48092441/5962715
কিরণ বেনি জোসেফ

উত্তর:


192

গুগল আই / ও অনুযায়ী এটি করার প্রস্তাবিত উপায়টি ব্যবহার না করে দয়া করে এই প্রভাবের জন্য কোনও গ্রন্থাগার ব্যবহার করবেন না। আপনার পুনর্ব্যবহারযোগ্যভিউয়ের অনবিন্দ ভিউহোল্ডার পদ্ধতিতে এটি করুন:

final boolean isExpanded = position==mExpandedPosition;
holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);
holder.itemView.setActivated(isExpanded);
holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mExpandedPosition = isExpanded ? -1:position;
        TransitionManager.beginDelayedTransition(recyclerView);
        notifyDataSetChanged();
    }
});
  • কোথায় বিবরণ আমার দৃষ্টিতে যে স্পর্শ প্রদর্শিত হবে (কলের বিবরণ আপনার ক্ষেত্রে। ডিফল্ট Visibility.GONE)।
  • এমএক্সপ্যান্ডেড পজিশনটি -1-তে প্রারম্ভিক পরিবর্তন হয়

এবং আপনি যে শীতল প্রভাবগুলি চেয়েছিলেন তার জন্য এগুলি আপনার তালিকা_রূপী বৈশিষ্ট্য হিসাবে ব্যবহার করুন:

android:background="@drawable/comment_background"
android:stateListAnimator="@animator/comment_selection"

যেখানে মন্তব্য_ব্যাকগ্রাউন্ডটি হ'ল:

<selector
xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="true"
android:enterFadeDuration="@android:integer/config_shortAnimTime"
android:exitFadeDuration="@android:integer/config_shortAnimTime">

<item android:state_activated="true" android:drawable="@color/selected_comment_background" />
<item android:drawable="@color/comment_background" />
</selector>

এবং মন্তব্য_ নির্বাচনটি হ'ল:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_activated="true">
    <objectAnimator
        android:propertyName="translationZ"
        android:valueTo="@dimen/z_card"
        android:duration="2000"
        android:interpolator="@android:interpolator/fast_out_slow_in" />
</item>

<item>
    <objectAnimator
        android:propertyName="translationZ"
        android:valueTo="0dp"
        android:duration="2000"
        android:interpolator="@android:interpolator/fast_out_slow_in" />
</item>
</selector>

22
এই কোডটি ব্যবহার করার সময় প্রসারিত-অ্যানিমেশনটি অদ্ভুত দেখাচ্ছে। প্রতিবার শীর্ষ আইটেম অদৃশ্য হয়ে যায় এবং সমস্ত কিছু এক অবস্থান সরিয়ে দেয়। আপনি কি কখনও অনুরূপ কিছু অভিজ্ঞতা আছে?
ক্রিস-পোলাক্স

6
আমি অ্যানিমেশনটি করার চেষ্টা করি তবে আমি এটি অ্যাডাপ্টারে প্রয়োগ করি তবে আমি TransitionManager.beginDelayedTransition(recyclerView);যদি পুনর্ব্যক্তিকর দৃশ্যের রেফারেন্সটি নাও পারি তবে এর সমাধান কী হবে ।
মার্টিন Serrano,

2
@ রণভীর এটির মতো কাজ করে। আমার দুটি একই ধরণের পুনর্ব্যবহারযোগ্য ভিউ রয়েছে তবে এটি কেবল একটির জন্য সঠিকভাবে কাজ করে। কেন জানি না। @ মার্টনডানিয়েল আপনাকে recyclerViewঅ্যাডাপ্টারের কনস্ট্রাক্টরের প্যারামিটার হিসাবে পাস করতে হবে
ক্রিস-পোলাক্স

26
এটি একটি ভয়াবহ পদ্ধতির। আমি বিশ্বাস করতে পারি না এটি গুগল আই / ও-তে প্রস্তাবিত হয়েছিল। এমনকি প্লেড প্রকল্পটি তদন্ত করে এবং এটি থেকে প্রয়োজনীয় সমস্ত কাজের পরিমাণ প্রয়োগ করার পরেও অ্যানিমেশনটি এখনও রিসাইক্লারভিউতে কিছু বড় বিঘ্ন ঘটায়, যেমন প্রথম / শেষ দৃশ্যমান আইটেম অকাল অদৃশ্য হয়ে যায়। অ্যানিমেশন চলার সময়ও স্ক্রোলিং সমস্ত জিনিসকে খারাপভাবে মেস করে। সাধারণভাবে, আমি মনে করি না যে এই পদ্ধতির কারণে সৃষ্ট সমস্ত সমস্যাগুলি সমাধান করা বিজ্ঞাপন হিসাবে বলা যেতে পারে "কেবল একটি লাইন রাখুন এবং সবকিছু ঠিক কাজ করবে"।
ভিটালি ওলশেভস্কি

6
এই ইস্যুটির জন্য আমাদের কি 2019 এ আরও কিছু টাটকা এবং সহজ উপায় আছে?
পোনোমারেঙ্কো ওলেহ

76

এটির জন্য, কেবল সহজ লাইনগুলি জটিল নয়

আপনার অনবিন্দ ভিহোল্ডার পদ্ধতিতে কোডের নীচে যুক্ত করুন

final boolean isExpanded = position==mExpandedPosition;
holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);
holder.itemView.setActivated(isExpanded);
holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mExpandedPosition = isExpanded ? -1:position;
        notifyItemChanged(position);
    }
});

mExpandedPosition -1 থেকে শুরু করে একটি গ্লোবাল ভেরিয়েবল

যারা চান তাদের কেবল একটি আইটেম প্রসারিত হয় এবং অন্যরা ধসে পড়ে যায়। এটা ব্যবহার কর

প্রথমে পূর্বের এক্সপেন্ডেডপজিশন = -1 দিয়ে একটি বৈশ্বিক পরিবর্তনশীল ঘোষণা করুন

তারপর

    final boolean isExpanded = position==mExpandedPosition;
    holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);
    holder.itemView.setActivated(isExpanded);

    if (isExpanded)
       previousExpandedPosition = position;

    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mExpandedPosition = isExpanded ? -1:position;
            notifyItemChanged(previousExpandedPosition);
            notifyItemChanged(position);
        }
    });

সম্পন্ন!!!. সরল ও বিনীত .. :)


দুর্দান্ত সমাধান এছাড়াও আমি সরাতে সেটিং বলতে চাই OnClickListenerথেকে গুলি onCreateViewHolderপরিবর্তেonBindViewHolder
YTerle

1
খুব ভাল কাজ করে, প্রায় সময় সম্পর্কে একটি শালীন সমাধান ছিল যা কেবল RecyclerViewকাজটি করতে দেয় , আমি বলতে চাইছি LayoutManagerঅন্যথায় এর বিন্দু কী যদি এটি বিন্যাসগুলি পরিচালনা না করে! এই সমাধানটি শীর্ষে ভোট দেওয়া সমাধানের চেয়ে ভাল কারণ এতে কম কোড রয়েছে, RecyclerViewহ্যান্ডেলগুলি জিনিসগুলিকে আরও ভালভাবে কাজ করতে দেয় !
মার্ক কেইন

1
"বিশদ" দর্শন কীভাবে যুক্ত করবেন তা বেশিরভাগই বুঝতে পারি নি। এটি প্রতিটি ধারকের পক্ষে স্থির হওয়া উচিত? যদি প্রতিটি তালিকার আইটেমগুলির জন্য আমার আলাদা আলাদা ভিউ যুক্ত করতে হয় তবে কী হবে?
বেকবট

@ বেকাবোটটি এমন একটি দৃষ্টিভঙ্গি যা আপনি ভাঙা আইটেমের সময় লুকিয়ে রাখতে চান
কিরণ বেনি জোসেফ

@ কিরানবেেনি জোসেফ হ্যাঁ, আমি বুঝতে পেরেছি। এক্ষেত্রে ভিউ সব আইটেমের জন্য একই হওয়া উচিত? আমি যদি বিভিন্ন আইটেমের জন্য আলাদা আলাদা ভিউ চাই?
বেকবট

72

এটি সেরা পদ্ধতির না বলা, তবে এটি আমার পক্ষে কার্যকর বলে মনে হচ্ছে।

পূর্ণ কোডটি এখানে পাওয়া যাবে: উদাহরণ কোড এখানে: https://github.com/dbleicher/recyclerview-grid-quickreturn

প্রথমে, আপনার ঘর / আইটেম বিন্যাসে প্রসারিত অঞ্চল যুক্ত করুন এবং ঘেরের ঘেরের বিন্যাসটিকে অ্যানিমেটলআউটচ্যাঞ্জস = "সত্য" করুন। এটি নিশ্চিত করবে যে প্রসারিত / পতন অ্যানিমেটেড হয়েছে:

<LinearLayout
    android:id="@+id/llCardBack"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:animateLayoutChanges="true"
    android:padding="4dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center|fill_horizontal"
        android:padding="10dp"
        android:gravity="center"
        android:background="@android:color/holo_green_dark"
        android:text="This is a long title to show wrapping of text in the view."
        android:textColor="@android:color/white"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/tvSubTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center|fill_horizontal"
        android:background="@android:color/holo_purple"
        android:padding="6dp"
        android:text="My subtitle..."
        android:textColor="@android:color/white"
        android:textSize="12sp" />

    <LinearLayout
        android:id="@+id/llExpandArea"
        android:visibility="gone"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="6dp"
            android:text="Item One" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="6dp"
            android:text="Item Two" />

    </LinearLayout>
</LinearLayout>

তারপরে, আপনার আরভি অ্যাডাপ্টারের ক্লাসটি ভিউ বাস্তবায়িত করুন nঅনিক্লিকলিস্টেনার যাতে আপনি ক্লিক করা আইটেমটিতে কাজ করতে পারেন। একটিকে প্রসারিত দৃষ্টির অবস্থান ধরে রাখতে কোনও int ফিল্ড যুক্ত করুন এবং এটিকে একটি নেতিবাচক মান থেকে শুরু করুন:

private int expandedPosition = -1;

অবশেষে, আপনার ভিউহোল্ডার, অনবিন্দ ভিউহোল্ডার () পদ্ধতিগুলি প্রয়োগ করুন এবং অনক্লিক () পদ্ধতিটি ওভাররাইড করুন। আপনি অনবিন্দ ভিউহোল্ডারে ভিউটি প্রসারিত করবেন যদি এটির অবস্থানটি "বর্ধিত অবস্থান" এর সমান হয় এবং যদি তা না লুকিয়ে থাকে। আপনি অনক্লিক শ্রোতার ক্ষেত্রে প্রসারিত পজিশনের মান সেট করেছেন:

@Override
public void onBindViewHolder(RVAdapter.ViewHolder holder, int position) {

    int colorIndex = randy.nextInt(bgColors.length);
    holder.tvTitle.setText(mDataset.get(position));
    holder.tvTitle.setBackgroundColor(bgColors[colorIndex]);
    holder.tvSubTitle.setBackgroundColor(sbgColors[colorIndex]);

    if (position == expandedPosition) {
        holder.llExpandArea.setVisibility(View.VISIBLE);
    } else {
        holder.llExpandArea.setVisibility(View.GONE);
    }
}

@Override
public void onClick(View view) {
    ViewHolder holder = (ViewHolder) view.getTag();
    String theString = mDataset.get(holder.getPosition());

    // Check for an expanded view, collapse if you find one
    if (expandedPosition >= 0) {
        int prev = expandedPosition;
        notifyItemChanged(prev);
    }
    // Set the current position to "expanded"
    expandedPosition = holder.getPosition();
    notifyItemChanged(expandedPosition);

    Toast.makeText(mContext, "Clicked: "+theString, Toast.LENGTH_SHORT).show();
}

/**
 * Create a ViewHolder to represent your cell layout
 * and data element structure
 */
public static class ViewHolder extends RecyclerView.ViewHolder {
    TextView tvTitle;
    TextView tvSubTitle;
    LinearLayout llExpandArea;

    public ViewHolder(View itemView) {
        super(itemView);

        tvTitle = (TextView) itemView.findViewById(R.id.tvTitle);
        tvSubTitle = (TextView) itemView.findViewById(R.id.tvSubTitle);
        llExpandArea = (LinearLayout) itemView.findViewById(R.id.llExpandArea);
    }
}

বিন্যাস পরিবর্তনের জন্য সিস্টেম-ডিফল্ট অ্যানিমেশন ব্যবহার করে এটি একবারে কেবল একটি আইটেম প্রসারিত করা উচিত। কমপক্ষে এটি আমার পক্ষে কাজ করে। আশা করি এটা সাহায্য করবে.


আমি জানি যে কীভাবে কেবল একটি আইটেম নির্বাচন করা যায়। আমি জানি না কীভাবে সেই আইটেমটিতে অ্যানিমেশন করা যায়। ডিফল্ট সিস্টেম অ্যানিমেশন সহ প্রসারিত / পতন অ্যানিমেশনটি খুব মসৃণ দেখাচ্ছে না।
stanete

1
আমি নিম্নলিখিতগুলি এখনও চেষ্টা করে দেখিনি, তবে এটি নিশ্চিতভাবে কাজ করবে বলে মনে হচ্ছে। : এ উত্তর চেক আউট stackoverflow.com/a/26443762/2259418
MojoTosh

2
@ ব্যবহারকারী2731584 - আমি এটি মনে করি না। তাদের উত্সটি (যা আমি বিশ্বাস করি) তা দেখে মনে হচ্ছে যে ললিপপ ঘড়িটি অ্যালার্মের তালিকা প্রদর্শন করতে একটি তালিকাভিউ ব্যবহার করছে। বিন্যাস: অ্যান্ড্রয়েড.googlesource.com/platform/packages/apps/DeskClock/+/… এই তালিকার প্রসারিত / পতন আইটেমগুলিকে সঞ্চার করার জন্য তাদের কাছে কাস্টম কোড রয়েছে বলে মনে হয়। নিম্নলিখিত উত্সটি দেখুন: android.googlesource.com/platform/packages/apps/DeskClock/+/…
মোজোটোস

1
@ মোজটোশ আপনি ঠিক বলেছেন তারা তালিকাটি ব্যবহার করছে এবং কোড ব্যবহার করে অ্যানিমেশন করছে। ফাইলগুলিতে expandAlarmফাংশন AlarmClockFragment.javaপ্রসারিত অংশটি কার্যকর করে।
ব্যবহারকারী 2731584

4
আমার কোনটি onClick()ওভাররাইড করা উচিত? কোন ব্যাপার onClickঅ্যাডাপ্টার হবে।
ভিকি লিওং

15

গ্রেডল সমর্থন সহ গ্রন্থাগারটি ব্যবহার করার জন্য খুব সহজ: https://github.com/cachapa/ExpandableLayout

লাইব্রেরি ডক্স থেকে সরাসরি:

<net.cachapa.expandablelayout.ExpandableLinearLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:el_duration="1000"
    app:el_expanded="true">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Click here to toggle expansion" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="Fixed height"
        app:layout_expandable="true" />

 </net.cachapa.expandablelayout.ExpandableLinearLayout>

আপনি আপনার চিহ্নটির পর বিস্তারযোগ্য মতামত শুধু ধারক উপর এই পদ্ধতি কোন কল: expand(), collapse()বাtoggle()


এটি কি এখনও এটি করার সর্বোত্তম উপায়? আপনি যা লিখেছেন তা অনুসরণ করার চেষ্টা করছি। আমার কিছু রিসাইকালের মতামত রয়েছে যা ক্লিক করার সময় আমি গ্রাফটি দেখানোর জন্য প্রসারিত করতে চাই
সিসারেলমনয়েড

10

আমি জানি মূল প্রশ্নটি পোস্ট হওয়ার পরে অনেক দিন হয়েছে। তবে আমি মনে করি আমার মতো ধীর ব্যক্তিদের জন্য @ হাইজেনবার্গের উত্তরটির কিছুটা ব্যাখ্যা সাহায্য করবে।

অ্যাডাপ্টার শ্রেণিতে দুটি ভেরিয়েবল হিসাবে ঘোষণা করুন

private int mExpandedPosition= -1;
private RecyclerView recyclerView = null;

তারপরে অনবিন্দভিউহোল্ডারটিতে মূল উত্তর হিসাবে দেওয়া হবে।

      // This line checks if the item displayed on screen 
      // was expanded or not (Remembering the fact that Recycler View )
      // reuses views so onBindViewHolder will be called for all
      // items visible on screen.
    final boolean isExpanded = position==mExpandedPosition;

        //This line hides or shows the layout in question
        holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);

        // I do not know what the heck this is :)
        holder.itemView.setActivated(isExpanded);

        // Click event for each item (itemView is an in-built variable of holder class)
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

 // if the clicked item is already expaned then return -1 
//else return the position (this works with notifyDatasetchanged )
                mExpandedPosition = isExpanded ? -1:position;
    // fancy animations can skip if like
                TransitionManager.beginDelayedTransition(recyclerView);
    //This will call the onBindViewHolder for all the itemViews on Screen
                notifyDataSetChanged();
            }
        });

এবং শেষ অবধি অ্যাডাপ্টারের ওভাররাইডে পুনর্ব্যবহারযোগ্য ভিউজটি পেতে

@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);

    this.recyclerView = recyclerView;
}

আশাকরি এটা সাহায্য করবে.


3
দুর্দান্ত এবং সহজ সমাধান। ছোট উন্নতি, ম্যাজিক নম্বর -1 এর পরিবর্তে রিসাইক্লার ভিউ.নো_পোসিটিশন ব্যবহার করুন।
ক্যাস্পার ব্যাং

8

তৃতীয় পক্ষের গ্রন্থাগারগুলি ব্যবহার করার দরকার নেই। এই বিষয়টিতে গুগল আই / ও ২০১ He এবং হাইজেনবার্গে প্রদর্শিত পদ্ধতিটিতে সামান্য টুইট করা কৌশলটি কার্যকর করে the

যেহেতু notifyDataSetChanged() সম্পূর্ণরূপে redrawsRecyclerView , notifyDataItemChanged()একটি ভাল বিকল্প (সেরা নয়) কারণ আমাদের অবস্থান এবং ViewHolderআমাদের নিষ্পত্তিস্থল রয়েছে এবং নির্দিষ্টটি একটি নির্দিষ্ট অবস্থানেnotifyDataItemChanged() কেবল নির্দিষ্ট ViewHolderকরে তোলে

তবে সমস্যাটি হ'ল উপরের ViewHolderক্লিকের অকাল অদৃশ্যতা এবং এর উত্থানটি notifyDataItemChanged()ব্যবহার করা হলেও মুছে ফেলা হয় না ।

নিম্নলিখিত কোড নেই অবলম্বন notifyDataSetChanged()বা notifyDataItemChanged()এবং কখন RecyclerView যেখানে প্রতিটি ViewHolder টি ব্যবহার এপিআই 23 এবং একটি যাদুমন্ত্র মত কাজ করে পরীক্ষা করা হয় CardViewএটা মূল উপাদান হিসাবে:

holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final boolean visibility = holder.details.getVisibility()==View.VISIBLE;

            if (!visibility)
            {
                holder.itemView.setActivated(true);
                holder.details.setVisibility(View.VISIBLE);
                if (prev_expanded!=-1 && prev_expanded!=position)
                {
                    recycler.findViewHolderForLayoutPosition(prev_expanded).itemView.setActivated(false);
                    recycler.findViewHolderForLayoutPosition(prev_expanded).itemView.findViewById(R.id.cpl_details).setVisibility(View.GONE);
                }
                prev_expanded = position;
            }
            else
            {
                holder.itemView.setActivated(false);
                holder.details.setVisibility(View.GONE);
            }
            TransitionManager.beginDelayedTransition(recycler);              
        }
});

prev_position এটি একটি গ্লোবাল পূর্ণসংখ্যা -1-এ শুরু হয়। detailsহ'ল সম্পূর্ণ দৃশ্য যা সংক্ষিপ্ত হয়ে যাওয়ার সময় প্রসারিত এবং ক্লকিংয়ের সময় প্রদর্শিত হয়।

বললেন, এর মূল উপাদান ViewHolderএকটি হল CardViewসঙ্গে foregroundএবংstateListAnimator এই বিষয়ে হাইজেনবের্গ দ্বারা ঠিক হিসাবে সংজ্ঞায়িত বৈশিষ্ট্যাবলী বলেন।

আপডেট: উপরোক্ত প্রদর্শনগুলি প্রিজিওসোলি বিস্তৃত আইটেমগুলির মধ্যে একটির প্রসারিত হলে ভেঙে পড়বে। এই আচরণটি পরিবর্তন করতে এবং প্রসারিত আইটেমটিকে অন্য আইটেমটি প্রসারিত করার পরেও তা রাখতে, আপনার নিম্নলিখিত কোডের প্রয়োজন the

if (row.details.getVisibility()!=View.VISIBLE)
    {
        row.details.setVisibility(View.VISIBLE);
        row.root.setActivated(true);
        row.details.animate().alpha(1).setStartDelay(500);
    }
    else
    {
        row.root.setActivated(false);
        row.details.setVisibility(View.GONE);
        row.details.setAlpha(0);
    }
    TransitionManager.beginDelayedTransition(recycler);

আপডেট: তালিকার শেষ আইটেমগুলি প্রসারিত করার সময়, এটি সম্পূর্ণ দৃশ্যমানতায় আনা হবে না কারণ প্রসারিত অংশটি পর্দার নীচে চলে যায়। স্ক্রিনের মধ্যে সম্পূর্ণ আইটেমটি পেতে নিম্নলিখিত কোডটি ব্যবহার করুন।

LinearLayoutManager manager = (LinearLayoutManager) recycler.getLayoutManager();
    int distance;
    View first = recycler.getChildAt(0);
    int height = first.getHeight();
    int current = recycler.getChildAdapterPosition(first);
    int p = Math.abs(position - current);
    if (p > 5) distance = (p - (p - 5)) * height;
    else       distance = p * height;
    manager.scrollToPositionWithOffset(position, distance);

গুরুত্বপূর্ণ: উপরোক্ত বিক্ষোভগুলি কাজ করার জন্য, তাদের কোডগুলিতে অবশ্যই পুনর্ব্যবহারযোগ্য ভিউ এবং এটির লেআউটম্যানেজারের একটি উদাহরণ রাখতে হবে (পরে নমনীয়তার জন্য)


ধন্যবাদ এই সমাধানটি আমার পক্ষে কাজ করে। আমি ব্যবহার এড়াতে চেষ্টা করি notifyItemChangedকারণ আমার কাছে ImageViewএকটি ইউআরএল থেকে ইমেজ লোড রয়েছে। notifyItemChangedআমার চিত্রটি পুনরায় লোড করা এটিকে অদ্ভুত দেখাচ্ছে
টম হুনি

যে লাইনটি এটি নখ করে TransitionManager.beginDelayedTransition(recycler);, এটি দুর্দান্ত। তবে আমি জানতে পেরেছি যে এই পদ্ধতিটি ব্যবহার করে, যদি আমি ধারাবাহিকভাবে কয়েকটি সারি স্প্যাম-ক্লিক করি তবে এটি শেষ পর্যন্ত অভ্যন্তরীণ ক্রাশকে ট্রিগার করে The specified child already has a parent. You must call removeView() on the child's parent first। আমি ধারণা করি এটি রিসাইক্লার দেখার সীমানায় ভিউ পুনর্ব্যবহারের কারণে, তবে আমি নিশ্চিতভাবে বলতে পারি না। কারও কি একই সমস্যা ছিল?
রজার ওবা

এটি কি এখনও এটি করার সর্বোত্তম উপায়? আপনি যা লিখেছেন তা অনুসরণ করার চেষ্টা করছি। আমার কিছু পুনর্ব্যবহারযোগ্য ভিউ রয়েছে যা ক্লিক করার সময় আমি কোনও গ্রাফ প্রদর্শন করতে প্রসারিত করতে চাই। ঠিক কী করতে হবে তা বোঝার জন্য আমার খুব কষ্ট হচ্ছে
স্য্রেসেলমনয়েড

কারও কি এই প্রয়োগের সম্পূর্ণ উদাহরণ রয়েছে? আমি একটি কাজের কোড উদাহরণ বলতে চাই। সাহায্য করুন. আমি বুঝতে পারি না কীভাবে এটি করতে পারি?
মুনাজা

7

বিস্তারযোগ্য / কলাপসিবল একটি অবস্থিত আইটেম বাস্তবায়নের প্রস্তাবিত উপায় ব্যবহার করার পর RecyclerViewউপর RecyclerView প্রসারিত / সঙ্কুচিত আইটেম উত্তর হাইজেনবের্গ আমার কিছু লক্ষণীয় নিদর্শন যখনই দেখা করেছি RecyclerViewআবাহন করার মাধ্যমে রিফ্রেশ করা হয় TransitionManager.beginDelayedTransition(ViewGroup)এবং পরবর্তীকালে notifyDatasetChanged()

তার আসল উত্তর:

final boolean isExpanded = position==mExpandedPosition;
holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);
holder.itemView.setActivated(isExpanded);
holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mExpandedPosition = isExpanded ? -1 : position;
        TransitionManager.beginDelayedTransition(recyclerView);
        notifyDataSetChanged();
    }
});

পরিবর্তিত:

final boolean isExpanded = position == mExpandedPosition;
holder.details.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
holder.view.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (mExpandedHolder != null) {
            mExpandedHolder.details.setVisibility(View.GONE);
            notifyItemChanged(mExpandedPosition);
        }
        mExpandedPosition = isExpanded ? -1 : holder.getAdapterPosition();
        mExpandedHolder = isExpanded ? null : holder;
        notifyItemChanged(holder.getAdapterPosition());
    }
}
  • বিশদটি হ'ল আপনি আইটেমটি প্রসারিত / পতনের সময় প্রদর্শন / লুকিয়ে রাখতে চান
  • এমএক্সপ্যানডপজিশন হ'ল intএটি প্রসারিত আইটেমের উপর নজর রাখে
  • mExpandedHolder একটি হয় ViewHolderআইটেমটি পতন সময় ব্যবহৃত

লক্ষ করুন যে, পদ্ধতি TransitionManager.beginDelayedTransition(ViewGroup)এবং notifyDataSetChanged()দ্বারা প্রতিস্থাপিত হয় notifyItemChanged(int)লক্ষ্য নির্দিষ্ট আইটেম এবং কিছু সামান্য সমন্বয় করতে।

পরিবর্তনের পরে, পূর্ববর্তী অযাচিত প্রভাবগুলি চলে যাওয়া উচিত। তবে এটি সঠিক সমাধান নাও হতে পারে। এটি কেবলমাত্র আমি যা চেয়েছিলাম তা করেছে, চোখের দোর মুছে ফেলা।

:: সম্পাদনা ::

ব্যাখ্যা জন্য, উভয় mExpandedPositionএবং mExpandedHolderglobals হয়।


কিভাবে এবং কোথায় এমএক্সপ্যানডহোল্ডার ঘোষণা এবং ব্যবহৃত হয় তা দয়া করে ব্যাখ্যা করুন?
ওয়ার্নার

1
@ ওয়ার্নার আমি উত্তরটি সম্পাদনা করেছি যেখানে এটি ঘোষিত হয়েছে তা দেখানোর জন্য। ব্যবহার স্নিপেটের পাশাপাশি উদ্দেশ্য হিসাবেও রয়েছে। এটি ভাঙ্গা, প্রসারিত আইটেম সঞ্চার করতে ব্যবহৃত হয়।
চান টেেক ওয়েই

অ্যানিমেশন সম্পর্কিত যতদূর আমি এই পদ্ধতির পছন্দ করি তবে আইটেমটি ক্লিক করার সময় আমি এই ছোট "বিবর্ণ" হয়ে যাচ্ছি। আপনারও কি পাশাপাশি বা অন্যভাবে বলা হয়েছে, এটি notifItemChanged () ব্যবহারের কারণে? drive.google.com/file/d/1GaU1fcjHEfSErYF50otQGLGsIWkSyQSe/…
কাজুমে

হ্যাঁ. যেমন আপনি অনুমান করেছেন, এটি দ্বারা সৃষ্ট notifyItemChanged()। আপনি ম্যানুয়ালি অ্যানিমেট করতে পারেন এবং আইটেমের উচ্চতা পরিবর্তন করতে এবং এতে ভিউ যুক্ত করতে পারেন।
চান টেেক ওয়েই 12

@ চ্যানটেকওয়ে: আপনার সমাধানটি ভাল কাজ করছে তবে যখনই আমি পুনর্ব্যবহারযোগ্য আইটেমটি সারিটি ভেঙে বা প্রসারিত করব তখনই সারি চিত্রের ঝাঁকুনি আছে ... এর কোনও সমাধান আছে কি?
প্রজ্ঞা মেন্ডিরাট্ট

3

আপনি ভিউহোল্ডার শ্রেণিতে অনক্লিক শ্রোতা সেট করার পরে নিম্নলিখিতটি করুন:

@Override
    public void onClick(View v) {
        final int originalHeight = yourLinearLayout.getHeight();
        animationDown(YourLinearLayout, originalHeight);//here put the name of you layout that have the options to expand.
    }

    //Animation for devices with kitkat and below
    public void animationDown(LinearLayout billChoices, int originalHeight){

        // Declare a ValueAnimator object
        ValueAnimator valueAnimator;
        if (!billChoices.isShown()) {
            billChoices.setVisibility(View.VISIBLE);
            billChoices.setEnabled(true);
            valueAnimator = ValueAnimator.ofInt(0, originalHeight+originalHeight); // These values in this method can be changed to expand however much you like
        } else {
            valueAnimator = ValueAnimator.ofInt(originalHeight+originalHeight, 0);

            Animation a = new AlphaAnimation(1.00f, 0.00f); // Fade out

            a.setDuration(200);
            // Set a listener to the animation and configure onAnimationEnd
            a.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    billChoices.setVisibility(View.INVISIBLE);
                    billChoices.setEnabled(false);
                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });
            // Set the animation on the custom view
            billChoices.startAnimation(a);
        }
        valueAnimator.setDuration(200);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            public void onAnimationUpdate(ValueAnimator animation) {
                Integer value = (Integer) animation.getAnimatedValue();
                billChoices.getLayoutParams().height = value.intValue();
                billChoices.requestLayout();
            }
        });


        valueAnimator.start();
    }
}

আমি মনে করি এটির সহায়তা করা উচিত, সাম্প্রতিক কল ভিউতে আমি একইভাবে Google বাস্তবায়ন করেছি এবং এটি করে does


2

আমি অবাক হয়েছি যে এখনও কোনও সংক্ষিপ্ত উত্তর নেই, যদিও এই জাতীয় একটি বিস্তৃত / পতনের অ্যানিমেশনটি কেবল মাত্র 2 লাইনের কোড সহ অর্জন করা খুব সহজ:

(recycler.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false // called once

এক্সাথে

notifyItemChanged(position) // in adapter, whenever a child view in item's recycler gets hidden/shown

সুতরাং আমার জন্য, নীচের লিঙ্কটিতে ব্যাখ্যাগুলি সত্যই কার্যকর ছিল: https://medium.com/@nikola.jakshic/how-to-expand-collapse-items-in-recyclerview-49a648a403a6


1
//Global Variable

private int selectedPosition = -1;

 @Override
    public void onBindViewHolder(final CustomViewHolder customViewHolder, final int i) {

        final int position = i;
        final GetProductCatalouge.details feedItem = this.postBeanses.get(i);
        customViewHolder.lly_main.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                selectedPosition = i;
                notifyDataSetChanged();
            }
        });
        if (selectedPosition == i) {

          if (customViewHolder.lly_hsn_code.getVisibility() == View.VISIBLE) {

            customViewHolder.lly_hsn_code.setVisibility(View.GONE);
            customViewHolder.lly_sole.setVisibility(View.GONE);
            customViewHolder.lly_sole_material.setVisibility(View.GONE);

        } else {

            customViewHolder.lly_hsn_code.setVisibility(View.VISIBLE);
            customViewHolder.lly_sole.setVisibility(View.VISIBLE);
            customViewHolder.lly_sole_material.setVisibility(View.VISIBLE);
        }


        } else {
            customViewHolder.lly_hsn_code.setVisibility(View.GONE);
            customViewHolder.lly_sole.setVisibility(View.GONE);
            customViewHolder.lly_sole_material.setVisibility(View.GONE);
        }
}

এখানে চিত্র বর্ণনা লিখুন


0

আপনারতে দুটি দর্শন প্রকার ব্যবহার করুন RVAdapter। একটি প্রসারিত বিন্যাসের জন্য এবং অন্যটি ধসে পড়ার জন্য। এবং যাদুটি এই ভিডিওটিতে 0: 42-এ ব্যবহার করে চেকআউট এফেক্টটি সেট android:animateLayoutChanges="true"করার সাথে ঘটেRecyclerView


এই আরও ভাল বোঝাতে মন? আমি এটি কাজ করে
যাচ্ছি

@sourlemonaid মূলত হিসাবে ব্যাখ্যা আপনি তালিকার জন্য একাধিক দৃশ্য ধরনের তৈরি stackoverflow.com/a/26245463/3731795 ... আপনি সূচক একটি ট্র্যাক যার জন্য আইটেমটি সম্প্রসারিত হয় থাক এবং আইটেম বাকি যে সময়ে ধসে করছে । এখন যদি (বর্তমান_তীম_ইনডেক্স == প্রসারিত_পরিচয়_ইন্ডেক্স) {VIEW_TYPE_EXPANDED} অন্য VI পুনর্বার VIVI_TYPE_COLLAPSED}
পেনডুদেভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.