পুনর্ব্যবহারযোগ্য ভিউ এবং বিভিন্ন ধরণের সারি মুদ্রাস্ফীতি পরিচালনা করে


124

আমি নতুনটির সাথে কাজ করার চেষ্টা করছি RecyclerView, তবে RecyclerViewবিভিন্ন ধরণের সারি / কার্ডভিউ স্ফীত হয়ে যাওয়ার কোনও উদাহরণ খুঁজে পেলাম না ।

সঙ্গে ListViewআমি ওভাররাইড getViewTypeCountএবং getItemViewType, সারি বিভিন্ন ধরনের পরিচালনা করার জন্য।

আমার কি "পুরানো" উপায়ে এটি করার কথা বা আমার কিছু করা উচিত LayoutManager? আমি ভাবছিলাম যে কেউ আমাকে সঠিক দিকে নির্দেশ করতে পারে কিনা। কারণ আমি কেবল এক প্রকারের সাথে উদাহরণগুলি পাই।

আমি কিছুটা আলাদা কার্ডের একটি তালিকা পেতে চাই। অথবা আমি কেবল এর অভ্যন্তর scrollViewদিয়ে একটি ব্যবহার করব cardViews... এটি অ্যাডাপ্টার ছাড়াই এবং তৈরি করতে পারি recyclerView?


আপনার আইটেম ধরণের মধ্যে পার্থক্য কি? পুনর্ব্যবহারযোগ্য পর্যালোচনাটি বিভিন্ন ধরণের ক্ষেত্রে কীভাবে প্রতিক্রিয়া দেখা উচিত? সাধারণভাবে, কোনও স্ক্রোলভিউ / তালিকার সাথে আপনি কিছুই করতে পারবেন না যা আপনি পুনর্ব্যবহারের সাথে করতে পারবেন না, তবে
অন্যভাবে নয়

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

যেকোনও একাধিক সারির লেআউট পুনর্ব্যবহারকারী কোড 2
কনসেপ্ট.ব্লগস্পট.


এই লিঙ্কটি দেখুন, এটি আপনার পক্ষে কার্যকর হবে: - stackoverflow.com/a/39972276/3946958
রবীন্দ্র কুশওয়াহ

উত্তর:


202

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

শেষ অবধি, অ্যাডাপ্টারে আপনি কী ধরণের দৃশ্য প্রদর্শন করছেন তা আপনি কীভাবে নির্ধারণ করবেন সে সম্পর্কে এটিই সমস্ত। একবার আপনি এটি সন্ধান পেয়ে গেলে, সহজেই নৌযান হওয়া উচিত (আসলে নয়, তবে কমপক্ষে আপনার এটি বাছাই করা হবে)।

অ্যাডাপ্টার দুটি পদ্ধতি প্রকাশ করে যা আপনার ওভাররাইড করা উচিত:

getItemViewType(int position)

এই পদ্ধতির ডিফল্ট প্রয়োগটি সর্বদা 0 ফিরে আসবে, ইঙ্গিত করে যে এখানে কেবল 1 ধরণের দর্শন রয়েছে। আপনার ক্ষেত্রে, এটি তেমন নয় এবং তাই আপনার সারিটি কোন ভিউয়ের সাথে সাদৃশ্যপূর্ণ তা জোর দেওয়ার একটি উপায় খুঁজে বের করতে হবে। আইওএসের বিপরীতে, যা সারি এবং বিভাগগুলি আপনার জন্য এটি পরিচালনা করে, এখানে নির্ভর করার জন্য আপনার কাছে কেবলমাত্র একটি সূচক থাকবে এবং কোনও অবস্থান কোনও বিভাগের শিরোনামের সাথে সংযোগ স্থাপন করে এবং কখন এটির সাথে সংযোগ স্থাপন করে তা জানতে আপনার বিকাশকারী দক্ষতা ব্যবহার করতে হবে you'll একটি সাধারণ সারি

createViewHolder(ViewGroup parent, int viewType)

আপনার যেকোন উপায়ে এই পদ্ধতিটি ওভাররাইড করা দরকার, তবে সাধারণত লোকেরা কেবল ভিউটাইপ পরামিতি উপেক্ষা করে। দর্শন প্রকার অনুসারে, আপনাকে সঠিক লেআউট রিসোর্স স্ফীত করতে হবে এবং সেই অনুযায়ী আপনার ভিউ ধারক তৈরি করতে হবে। রিসাইক্লারভিউ বিভিন্ন উপত্যকার ধরণের পুনর্ব্যবহার করে এমনভাবে পরিচালনা করবে যা বিভিন্ন দর্শন প্রকারের সংঘাতকে এড়িয়ে চলে।

যদি আপনি কোনও ডিফল্ট লেআউটম্যানেজার যেমন ব্যবহার করার পরিকল্পনা করে থাকেন তবে আপনার LinearLayoutManagerভাল হওয়া উচিত। আপনি যদি নিজের লেআউট ম্যানেজার বাস্তবায়ন করার পরিকল্পনা করে থাকেন তবে আপনাকে আরও কঠোর পরিশ্রম করতে হবে। আপনার সত্যিকারের সাথে কাজ করতে হবে এমন একমাত্র এপিআই হ'ল findViewByPosition(int position)যা নির্দিষ্ট অবস্থানে প্রদত্ত ভিউ দেয়। যেহেতু আপনি সম্ভবত এই ভিউটি কী ধরণের নির্ভর করে এটি আলাদাভাবে ছড়িয়ে দিতে চান তাই আপনার কাছে কয়েকটি বিকল্প রয়েছে:

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

  2. যেহেতু আপনার কোনও ফাংশন প্রয়োজন যা কোনও অবস্থানের সাথে কোন অবস্থানের সাথে সম্পর্কিত কিনা তা নির্ধারণ করে, আপনি পাশাপাশি এই পদ্ধতিটি কোনওভাবে বিশ্বব্যাপী অ্যাক্সেসযোগ্য করে তুলতে পারেন (সম্ভবত কোনও সিঙ্গলটন শ্রেণি যা ডেটা পরিচালনা করে?) এবং তারপরে আপনি কেবল সেই পদ্ধতি অনুসারে প্রশ্নটি করতে পারেন অবস্থান।

এখানে একটি কোড নমুনা:

// in this sample, I use an object array to simulate the data of the list. 
// I assume that if the object is a String, it means I should display a header with a basic title.
// If not, I assume it's a custom model object I created which I will use to bind my normal rows.
private Object[] myData;

public static final int ITEM_TYPE_NORMAL = 0;
public static final int ITEM_TYPE_HEADER = 1;

public class MyAdapter extends Adapter<ViewHolder> {

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        if (viewType == ITEM_TYPE_NORMAL) {
            View normalView = LayoutInflater.from(getContext()).inflate(R.layout.my_normal_row, null);
            return new MyNormalViewHolder(normalView); // view holder for normal items
        } else if (viewType == ITEM_TYPE_HEADER) {
            View headerRow = LayoutInflater.from(getContext()).inflate(R.layout.my_header_row, null);
            return new MyHeaderViewHolder(headerRow); // view holder for header items
        }
    }


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

        final int itemType = getItemViewType(position);

        if (itemType == ITEM_TYPE_NORMAL) {
            ((MyNormalViewHolder)holder).bindData((MyModel)myData[position]);
        } else if (itemType == ITEM_TYPE_HEADER) {
            ((MyHeaderViewHolder)holder).setHeaderText((String)myData[position]);
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (myData[position] instanceof String) {
            return ITEM_TYPE_HEADER;
        } else {
            return ITEM_TYPE_NORMAL;
        }
    }

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

এই দর্শকদের কীভাবে দেখা উচিত তার একটি নমুনা এখানে দেওয়া হল:

public MyHeaderViewHolder extends ViewHolder {

    private TextView headerLabel;    

    public MyHeaderViewHolder(View view) {
        super(view);

        headerLabel = (TextView)view.findViewById(R.id.headerLabel);
    }

    public void setHeaderText(String text) {
        headerLabel.setText(text);
    }    
}


public MyNormalViewHolder extends ViewHolder {

    private TextView titleLabel;
    private TextView descriptionLabel;    

    public MyNormalViewHolder(View view) {
        super(view);

        titleLabel = (TextView)view.findViewById(R.id.titleLabel);
        descriptionLabel = (TextView)view.findViewById(R.id.descriptionLabel);
    }

    public void bindData(MyModel model) {
        titleLabel.setText(model.getTitle());
        descriptionLabel.setText(model.getDescription());
    }    
}

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

// Assume names & descriptions are non-null and have the same length.
// Assume names are alphabetized
private void processDataSource(String[] names, String[] descriptions) {
    String nextFirstLetter = "";
    String currentFirstLetter;

    List<Object> data = new ArrayList<Object>();

    for (int i = 0; i < names.length; i++) {
        currentFirstLetter = names[i].substring(0, 1); // get the 1st letter of the name

        // if the first letter of this name is different from the last one, add a header row
        if (!currentFirstLetter.equals(nextFirstLetter)) {
            nextFirstLetter = currentFirstLetter;
            data.add(nextFirstLetter);
        }

        data.add(new MyModel(names[i], descriptions[i]));
    }

    myData = data.toArray();
}

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


খুব সুন্দর, এবং আমি এই জাতীয় সমস্যা সমাধানের
এমট 8787

Recyelview যে ভিতরে বিভিন্ন সারি infalting জন্য আরেকটি উদাহরণ: - stackoverflow.com/a/39972276/3946958
রবীন্দ্র Kushwaha

হওয়া উচিতnames[i].substring(0, 1)
কাইল

1
ভিন্ন ভিন্ন আইটেমগুলির সাথে পুনর্ব্যবহারকারী দর্শনের জন্য স্প্যানসাইজলুকআপটিও দেখতে ভাল ধারণা। stackoverflow.com/questions/26869312/…
মাহোরি

এটা কার্যকরী. এই উত্তরের ভিত্তিতে আমার এনাম ব্যবহার করে অ্যাডাপ্টারে মাল্টি টাইপ ভিউ বাস্তবায়নের একটি ধারণাও রয়েছে। এনামের এমন পদ্ধতি থাকবে onCreateViewHolderযা আমাদের দেখার ধারক তৈরি করতে সহায়তা করে। : আরও বিস্তারিত জানার জন্য আপনি আমার ভাগ চেক করতে পারেন stackoverflow.com/questions/47245398/...
quangson91

114

কৌশলটি হল ভিউহোল্ডারের সাবক্ল্যাস তৈরি করা এবং তারপরে তাদের কাস্ট করা।

public class GroupViewHolder extends RecyclerView.ViewHolder {
    TextView mTitle;
    TextView mContent;
    public GroupViewHolder(View itemView) {
        super (itemView);
        // init views...
    }
}

public class ImageViewHolder extends RecyclerView.ViewHolder {
    ImageView mImage;
    public ImageViewHolder(View itemView) {
        super (itemView);
        // init views...
    }
}

private static final int TYPE_IMAGE = 1;
private static final int TYPE_GROUP = 2;  

এবং তারপরে রানটাইমের সময় এমন কিছু করুন:

@Override
public int getItemViewType(int position) {
    // here your custom logic to choose the view type
    return position == 0 ? TYPE_IMAGE : TYPE_GROUP;
}

@Override
public void onBindViewHolder (ViewHolder viewHolder, int i) {

    switch (viewHolder.getItemViewType()) {

        case TYPE_IMAGE:
            ImageViewHolder imageViewHolder = (ImageViewHolder) viewHolder;
            imageViewHolder.mImage.setImageResource(...);
            break;

        case TYPE_GROUP:
            GroupViewHolder groupViewHolder = (GroupViewHolder) viewHolder;
            groupViewHolder.mContent.setText(...)
            groupViewHolder.mTitle.setText(...);
            break;
    }
}

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


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

Recyelview যে ভিতরে বিভিন্ন সারি infalting জন্য আরেকটি উদাহরণ: - stackoverflow.com/questions/39971350/...
রবীন্দ্র Kushwaha

1
স্যুইচ কেস মানগুলিতে ভিউ ধারক বেস baseালাইয়ের পরিবর্তে কি কোনও জেনেরিক সমাধান রয়েছে?
ওয়াহিদ গাদির 21

33

গিল দুর্দান্ত উত্তর অনুসারে আমি গিলের ব্যাখ্যা অনুসারে গেট আইটেম ভিউ টাইপকে ওভাররাইড করে সমাধান করেছি। তাঁর উত্তর দুর্দান্ত এবং সঠিক হিসাবে চিহ্নিত করতে হবে। যাই হোক না কেন, আমি স্কোর পৌঁছানোর জন্য কোড যুক্ত করেছি:

আপনার পুনর্ব্যবহারযোগ্য অ্যাডাপ্টারে:

@Override
public int getItemViewType(int position) {
    int viewType = 0;
    // add here your booleans or switch() to set viewType at your needed
    // I.E if (position == 0) viewType = 1; etc. etc.
    return viewType;
}

@Override
public FileViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType == 0) {
        return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.my_layout_for_first_row, parent, false));
    }

    return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.my_other_rows, parent, false));
}

এটি করে, আপনি যে কোনও সারিটির জন্য যে কোনও কাস্টম বিন্যাস সেট করতে পারেন!


18
কেবল একটি ছোট্ট মন্তব্য: অনক্রিটভিউহোল্ডারটির দ্বিতীয় প্যারামিটারটি সূচি নয়, ভিউটাইপ হওয়া উচিত। এপিআই অনুসারে: developer.android.com/references/android/support/v7/widget/… , int)
মার্ক মার্টিনসন

তবে ব্যবহারকারী যখন সেই মুহুর্তে দ্রুত কিছুটা অদ্ভুত আউটপুট পাচ্ছেন তখন কী হবে।
আরজেজ সাতভারা

15

এটি বেশ কৌতূহলোদ্দীপক তবে এটি খুব শক্ত, কেবল নীচের কোডটি অনুলিপি করুন এবং আপনি হয়ে গেছেন

package com.yuvi.sample.main;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;


import com.yuvi.sample.R;

import java.util.List;

/**
 * Created by yubraj on 6/17/15.
 */

public class NavDrawerAdapter extends RecyclerView.Adapter<NavDrawerAdapter.MainViewHolder> {
    List<MainOption> mainOptionlist;
    Context context;
    private static final int TYPE_PROFILE = 1;
    private static final int TYPE_OPTION_MENU = 2;
    private int selectedPos = 0;
    public NavDrawerAdapter(Context context){
        this.mainOptionlist = MainOption.getDrawableDataList();
        this.context = context;
    }

    @Override
    public int getItemViewType(int position) {
        return (position == 0? TYPE_PROFILE : TYPE_OPTION_MENU);
    }

    @Override
    public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType){
            case TYPE_PROFILE:
                return new ProfileViewHolder(LayoutInflater.from(context).inflate(R.layout.row_profile, parent, false));
            case TYPE_OPTION_MENU:
                return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.row_nav_drawer, parent, false));
        }
        return null;
    }

    @Override
    public void onBindViewHolder(MainViewHolder holder, int position) {
        if(holder.getItemViewType() == TYPE_PROFILE){
            ProfileViewHolder mholder = (ProfileViewHolder) holder;
            setUpProfileView(mholder);
        }
        else {
            MyViewHolder mHolder = (MyViewHolder) holder;
            MainOption mo = mainOptionlist.get(position);
            mHolder.tv_title.setText(mo.title);
            mHolder.iv_icon.setImageResource(mo.icon);
            mHolder.itemView.setSelected(selectedPos == position);
        }
    }

    private void setUpProfileView(ProfileViewHolder mholder) {

    }

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




public class MyViewHolder extends MainViewHolder{
    TextView tv_title;
    ImageView iv_icon;

    public MyViewHolder(View v){
        super(v);
        this.tv_title = (TextView) v.findViewById(R.id.tv_title);
        this.iv_icon = (ImageView) v.findViewById(R.id.iv_icon);
        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Redraw the old selection and the new
                notifyItemChanged(selectedPos);
                selectedPos = getLayoutPosition();
                notifyItemChanged(selectedPos);
            }
        });
    }
}
    public class ProfileViewHolder extends MainViewHolder{
        TextView tv_name, login;
        ImageView iv_profile;

        public ProfileViewHolder(View v){
            super(v);
            this.tv_name = (TextView) v.findViewById(R.id.tv_profile);
            this.iv_profile = (ImageView) v.findViewById(R.id.iv_profile);
            this.login = (TextView) v.findViewById(R.id.tv_login);
        }
    }

    public void trace(String tag, String message){
        Log.d(tag , message);
    }
    public class MainViewHolder extends  RecyclerView.ViewHolder {
        public MainViewHolder(View v) {
            super(v);
        }
    }


}

উপভোগ করুন !!!!


আমার ভিউহোল্ডার 1 এর লেআউটটি myLaout1.xML নামে আছে এবং এতে স্ক্রোলভিউ রয়েছে। সুতরাং এখন যখন আমি এই জিনিসটি স্ক্রোল করি তখন পুনর্ব্যবহারযোগ্য দৃশ্যটি স্ক্রোল হয়। ভিউহোল্ডার 1 এর লিখিত সামগ্রী কীভাবে স্ক্রোল করবেন
অঙ্কেশ কুমার জাইসানসরিয়া

3

আমরা নীচের দিক থেকে একক পুনর্ব্যবহারযোগ্য ভিউতে একাধিক ভিউ অর্জন করতে পারি: -

গ্রেডলে নির্ভরতা সুতরাং নীচে কোড যুক্ত করুন: -

compile 'com.android.support:cardview-v7:23.0.1'
compile 'com.android.support:recyclerview-v7:23.0.1'

এক্সএমএলে রিসাইক্লারভিউ

<android.support.v7.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

ক্রিয়াকলাপ কোড

private RecyclerView mRecyclerView;
private CustomAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private String[] mDataset = {“Data - one ”, Data - two”,
    Showing data three”, Showing data four”};
private int mDatasetTypes[] = {DataOne, DataTwo, DataThree}; //view types
 
...
 
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mLayoutManager = new LinearLayoutManager(MainActivity.this);
mRecyclerView.setLayoutManager(mLayoutManager);
//Adapter is created in the last step
mAdapter = new CustomAdapter(mDataset, mDataSetTypes);
mRecyclerView.setAdapter(mAdapter);

প্রথম এক্সএমএল

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cardview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/ten"
    android:elevation="@dimen/hundered”
    card_view:cardBackgroundColor=“@color/black“>
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding=“@dimen/ten">
 
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=“Fisrt”
            android:textColor=“@color/white“ />
 
        <TextView
            android:id="@+id/temp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/ten"
            android:textColor="@color/white"
            android:textSize="30sp" />
    </LinearLayout>
 
</android.support.v7.widget.CardView>

দ্বিতীয় এক্সএমএল

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cardview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/ten"
    android:elevation="100dp"
    card_view:cardBackgroundColor="#00bcd4">
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="@dimen/ten">
 
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=“DataTwo”
            android:textColor="@color/white" />
 
        <TextView
            android:id="@+id/score"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/ten"
            android:textColor="#ffffff"
            android:textSize="30sp" />
    </LinearLayout>
 
</android.support.v7.widget.CardView>

তৃতীয় এক্সএমএল

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cardview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/ten"
    android:elevation="100dp"
    card_view:cardBackgroundColor="@color/white">
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="@dimen/ten">
 
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=“DataThree” />
 
        <TextView
            android:id="@+id/headline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/ten"
            android:textSize="25sp" />
 
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/ten"
            android:id="@+id/read_more"
            android:background="@color/white"
            android:text=“Show More/>
    </LinearLayout>
 
</android.support.v7.widget.CardView>

এখন অ্যাডাপ্টার তৈরি করার সময় এবং এটি একই পুনর্ব্যবহারকারী দৃশ্যে বিভিন্ন -2 ভিউ দেখানোর জন্য মূল এটি তাই দয়া করে এই কোডটির ফোকাসটি পুরোপুরি পরীক্ষা করুন: -

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
    private static final String TAG = "CustomAdapter";
 
    private String[] mDataSet;
    private int[] mDataSetTypes;
 
    public static final int dataOne = 0;
    public static final int dataTwo = 1;
    public static final int dataThree = 2;
 
 
    public static class ViewHolder extends RecyclerView.ViewHolder {
        public ViewHolder(View v) {
            super(v);
        }
    }
 
    public class DataOne extends ViewHolder {
        TextView temp;
 
        public DataOne(View v) {
            super(v);
            this.temp = (TextView) v.findViewById(R.id.temp);
        }
    }
 
    public class DataTwo extends ViewHolder {
        TextView score;
 
        public DataTwo(View v) {
            super(v);
            this.score = (TextView) v.findViewById(R.id.score);
        }
    }
 
    public class DataThree extends ViewHolder {
        TextView headline;
        Button read_more;
 
        public DataThree(View v) {
            super(v);
            this.headline = (TextView) v.findViewById(R.id.headline);
            this.read_more = (Button) v.findViewById(R.id.read_more);
        }
    }
 
 
    public CustomAdapter(String[] dataSet, int[] dataSetTypes) {
        mDataSet = dataSet;
        mDataSetTypes = dataSetTypes;
    }
 
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        View v;
        if (viewType == dataOne) {
            v = LayoutInflater.from(viewGroup.getContext())
                    .inflate(R.layout.weather_card, viewGroup, false);
 
            return new DataOne(v);
        } else if (viewType == dataTwo) {
            v = LayoutInflater.from(viewGroup.getContext())
                    .inflate(R.layout.news_card, viewGroup, false);
            return new DataThree(v);
        } else {
            v = LayoutInflater.from(viewGroup.getContext())
                    .inflate(R.layout.score_card, viewGroup, false);
            return new DataTwo(v);
        }
    }
 
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int position) {
        if (viewHolder.getItemViewType() == dataOne) {
            DataOne holder = (DataOne) viewHolder;
            holder.temp.setText(mDataSet[position]);
        }
        else if (viewHolder.getItemViewType() == dataTwo) {
            DataThree holder = (DataTwo) viewHolder;
            holder.headline.setText(mDataSet[position]);
        }
        else {
            DataTwo holder = (DataTwo) viewHolder;
            holder.score.setText(mDataSet[position]);
        }
    }
 
    @Override
    public int getItemCount() {
        return mDataSet.length;
    }
 
   @Override
    public int getItemViewType(int position) {
        return mDataSetTypes[position];
    }
}

আপনি আরও তথ্যের জন্য এই লিঙ্কটি পরীক্ষা করতে পারেন ।


তবে এটি দুর্দান্ত কাজ করে তবে যখন আমি উপরে থেকে নীচে থেকে দ্রুত স্ক্রোল করছি এবং বিপরীতে আমি কিছু অদ্ভুত আউটপুট পাচ্ছি ... মানে ডেটা সঠিকভাবে সেট করা হয়নি, এর সমাধান কী?
Rjz সাতভারা

2

আপনি getItemViewType()পদ্ধতি প্রয়োগ করতে হবে RecyclerView.Adapter। এই পদ্ধতির ডিফল্ট onCreateViewHolder(ViewGroup parent, int viewType)প্রয়োগের viewTypeমাধ্যমে রিটার্ন আসে 0। প্রথমত আপনার পুনর্ব্যবহারযোগ্য দেখার উদ্দেশ্যে এবং আইটেমের অবস্থানটি ফিরিয়ে আনবে এমন কোনও getItemViewType()পদ্ধতিতে আপনি যে পদ্ধতিটি পাস করতে পারবেন তাতে ওভাররাইড করতে হবে viewTypeএমন দৃশ্যের জন্য আইটেমের ধরণের অবস্থানের প্রয়োজন । কোড নমুনা নীচে দেওয়া হয়

@Override
public MyViewholder onCreateViewHolder(ViewGroup parent, int viewType) {
    int listViewItemType = getItemViewType(viewType);
    switch (listViewItemType) {
         case 0: return new ViewHolder0(...);
         case 2: return new ViewHolder2(...);
    }
}

@Override
public int getItemViewType(int position) {   
    return position;
}

// and in the similar way you can set data according 
// to view holder position by passing position in getItemViewType
@Override
public void onBindViewHolder(MyViewholder viewholder, int position) {
    int listViewItemType = getItemViewType(position);
    // ...
}

2

getItemViewType (int পজিশন) কী

আমার মতে, এই ধরণের পুনর্ব্যবহারযোগ্য ভিউ তৈরির সূচনা পয়েন্টটি এই পদ্ধতির জ্ঞান। যেহেতু এই পদ্ধতিটি ওভাররাইড করার জন্য isচ্ছিক তাই এটি রিসিলারভিউ ক্লাসে ডিফল্টরূপে দৃশ্যমান নয় যা ফলস্বরূপ অনেক বিকাশকারী (আমাকে সহ) ভাবতে শুরু করে যে কোথায় শুরু করতে হবে। একবার আপনি জানতে পারবেন যে এই পদ্ধতিটি বিদ্যমান, এই জাতীয় পুনর্ব্যবহারযোগ্য ভিউ তৈরি করা একটি কেকওয়াক হবে।

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

এটা কিভাবে করতে হবে ?

আপনি RecyclerViewবিভিন্ন ভিউ (ভিউহোল্ডার) এর যে কোনও সংখ্যক সহ একটি তৈরি করতে পারেন । তবে আরও ভাল পাঠযোগ্যতার জন্য RecyclerViewদুটি দিয়ে একটি উদাহরণ নিতে পারি Viewholders
এই 3 টি সহজ পদক্ষেপ মনে রাখুন এবং আপনি যেতে ভাল হবে।

  • পাবলিক ইনটাকে ওভাররাইড করুন getItemViewType(int position)
  • অনক্রিটভিউহোল্ডার ViewType() পদ্ধতির উপর ভিত্তি করে বিভিন্ন ভিউহোল্ডারগুলি ফিরিয়ে দিন
  • onBindViewHolder()পদ্ধতিতে আইটেমভিউ টাইপের উপর ভিত্তি করে ভিউ পপুলেট করুন

    আপনার জন্য এখানে একটি কোড স্নিপেট

    public class YourListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    
        private static final int LAYOUT_ONE= 0;
        private static final int LAYOUT_TWO= 1;
    
        @Override
        public int getItemViewType(int position)
        {
            if(position==0)
               return LAYOUT_ONE;
            else
               return LAYOUT_TWO;
        }
    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    
            View view =null;
            RecyclerView.ViewHolder viewHolder = null;
    
            if(viewType==LAYOUT_ONE)
            {
               view = LayoutInflater.from(parent.getContext()).inflate(R.layout.one,parent,false);
               viewHolder = new ViewHolderOne(view);
            }
            else
            {
               view = LayoutInflater.from(parent.getContext()).inflate(R.layout.two,parent,false);
               viewHolder= new ViewHolderTwo(view);
            }
    
            return viewHolder;
        }
    
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
    
           if(holder.getItemViewType()== LAYOUT_ONE)
           {
               // Typecast Viewholder 
               // Set Viewholder properties 
               // Add any click listener if any 
           }
           else {
    
               ViewHolderOne vaultItemHolder = (ViewHolderOne) holder;
               vaultItemHolder.name.setText(displayText);
               vaultItemHolder.name.setOnClickListener(new View.OnClickListener() {
                   @Override
                   public void onClick(View v) {
                       .......
                   }
               });
    
           }
    
       }
    
       /****************  VIEW HOLDER 1 ******************//
    
       public class ViewHolderOne extends RecyclerView.ViewHolder {
    
           public TextView name;
    
           public ViewHolderOne(View itemView) {
           super(itemView);
           name = (TextView)itemView.findViewById(R.id.displayName);
           }
       }
    
    
      //****************  VIEW HOLDER 2 ******************//
    
      public class ViewHolderTwo extends RecyclerView.ViewHolder{
    
           public ViewHolderTwo(View itemView) {
           super(itemView);
    
               ..... Do something
           }
      }
    }

গিটহাব কোড:

এখানে এমন একটি প্রকল্প রয়েছে যেখানে আমি একাধিক ভিউহোল্ডারগুলির সাথে একটি রিসাইক্লার ভিউ প্রয়োগ করেছি।


একই কিন্তু একাধিক ডেটা সেট থাকা সম্পর্কে কী?
esQmo_

আপনি কি বোঝাতে চেয়েছেন? @esQmo_
রোহিত সিং

আমি বলতে চাইছি যদি প্রতিটি ভাইোল্ডারের কাছে আলাদা ডেটাসেট (ডেটা উত্স) থাকে?
esQmo_

1

আপনি কেবল আইটেমভিউটাইপটি ফিরে আসতে পারেন এবং এটি ব্যবহার করতে পারেন। নীচের কোডটি দেখুন:

@Override
public int getItemViewType(int position) {

    Message item = messageList.get(position);
    // return my message layout
    if(item.getUsername() == Message.userEnum.I)
        return R.layout.item_message_me;
    else
        return R.layout.item_message; // return other message layout
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(viewType, viewGroup, false);
    return new ViewHolder(view);
}

1

আপনি গ্রন্থাগারটি ব্যবহার করতে পারেন: https://github.com/vivchar/RendererRecyclerViewAdapter

mRecyclerViewAdapter = new RendererRecyclerViewAdapter(); /* included from library */
mRecyclerViewAdapter.registerRenderer(new SomeViewRenderer(SomeModel.TYPE, this));
mRecyclerViewAdapter.registerRenderer(...); /* you can use several types of cells */

প্রতিটি আইটেমের জন্য, আপনাকে ভিউ রেন্ডারার, ভিউহোল্ডার, সামমোডেল প্রয়োগ করতে হবে:

ভিউহোল্ডার - এটি রিসাইক্লার দৃশ্যের একটি সাধারণ ভিউ ধারক।

সামমোডেল - এটি ItemModelইন্টারফেস সহ আপনার মডেল

public class SomeViewRenderer extends ViewRenderer<SomeModel, SomeViewHolder> {

    public SomeViewRenderer(final int type, final Context context) {
        super(type, context);
    }

    @Override
    public void bindView(@NonNull final SomeModel model, @NonNull final SomeViewHolder holder) {
       holder.mTitle.setText(model.getTitle());
    }

    @NonNull
    @Override
    public SomeViewHolder createViewHolder(@Nullable final ViewGroup parent) {
        return new SomeViewHolder(LayoutInflater.from(getContext()).inflate(R.layout.some_item, parent, false));
    }
}

আরও বিশদ জন্য আপনি ডকুমেন্টেশন দেখতে পারেন।


0

আপনি এই লাইব্রেরিটি ব্যবহার করতে পারেন:
https://github.com/kmfish/ মাল্টিটাইপলিস্টভিউ অ্যাডাপ্টার (আমার লেখা)

  • একটি ঘরের কোড পুনরায় ব্যবহার করা
  • আরও ভাল সম্প্রসারণ
  • আরও ভাল decoupling

অ্যাডাপ্টার সেটআপ করুন:

adapter = new BaseRecyclerAdapter();
adapter.registerDataAndItem(TextModel.class, LineListItem1.class);
adapter.registerDataAndItem(ImageModel.class, LineListItem2.class);
adapter.registerDataAndItem(AbsModel.class, AbsLineItem.class);

প্রতিটি লাইন আইটেমের জন্য:

public class LineListItem1 extends BaseListItem<TextModel, LineListItem1.OnItem1ClickListener> {

    TextView tvName;
    TextView tvDesc;


    @Override
    public int onGetLayoutRes() {
        return R.layout.list_item1;
    }

    @Override
    public void bindViews(View convertView) {
        Log.d("item1", "bindViews:" + convertView);
        tvName = (TextView) convertView.findViewById(R.id.text_name);
        tvDesc = (TextView) convertView.findViewById(R.id.text_desc);

        tvName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (null != attachInfo) {
                    attachInfo.onNameClick(getData());
                }
            }
        });
        tvDesc.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (null != attachInfo) {
                    attachInfo.onDescClick(getData());
                }
            }
        });

    }

    @Override
    public void updateView(TextModel model, int pos) {
        if (null != model) {
            Log.d("item1", "updateView model:" + model + "pos:" + pos);
            tvName.setText(model.getName());
            tvDesc.setText(model.getDesc());
        }
    }

    public interface OnItem1ClickListener {
        void onNameClick(TextModel model);
        void onDescClick(TextModel model);
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.