রিসাইক্লার ভিউয়ের জন্য কি অ্যাডহাইডারভিউ সমতুল্য?


290

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

সম্পাদনা 2 (যোগ করা খণ্ড লেআউট):

লগ স্টেটমেন্ট যুক্ত করার পরে, দেখে মনে হয় যে getViewType কেবল কখনও 0-এর একটি অবস্থান পায় এটির ফলে অনক্রিটভিউ কেবল একটি বিন্যাস লোড করে:

10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemCount: 5
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemCount: 5
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemCount: 5
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemCount: 5
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemCount: 5
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemCount: 5
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemCount: 5
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemCount: 5
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemCount: 5
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemCount: 5
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemCount: 5
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemViewType position: 0
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemViewType position: 0
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> getItemViewType position: 0
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> onCreateViewHolder, viewtype: 0
10-26 16:32:53.766    5449-5449/co.testapp I/logger info Adapter-> onBindViewHolder, viewType: 0

কমেন্টফ্রেগমেন্টটি লোড করার জন্য টুকরাটির স্থানান্তর

@Override
public void onPhotoFeedItemClick(View view, int position) {
    if (fragmentManager == null)
        fragmentManager = getSupportFragmentManager();

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    if (view.getId() == R.id.button_comment){
        CommentFragment commentFragment = CommentFragment.newInstance("","", position);
        fragmentTransaction.add(R.id.main_activity, commentFragment,"comment_fragment_tag");
        fragmentTransaction.addToBackStack(Constants.TAG_COMMENTS);
        fragmentTransaction.commit();
    }
}

খণ্ডটির অনক্রিট ভিউ:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_comment, container, false);
    mRecyclerView = (RecyclerView) view.findViewById(R.id.list_recylclerview);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(_context));
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());
    mAdapter = new CommentAdapter(R.layout.row_list_comments, R.layout.row_header_comments, _context, comments);
    mRecyclerView.setAdapter(mAdapter);
    return view;
}

রিসাইক্য ভিউযুক্ত খণ্ড:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    tools:context="co.testapp.fragments.CommentFragment"
    android:background="@color/white">
        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical">
            <android.support.v7.widget.RecyclerView
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/list_recylclerview"
                android:layout_width="match_parent"
                android:layout_height="200dp" />
        </RelativeLayout>
</RelativeLayout>

মন্তব্য সারি বিন্যাস:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent" android:layout_margin="10dp"
    android:background="@color/white">
    <!--Profile Picture-->
    <ImageView
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:id="@+id/profile_picture"
        android:background="@color/blue_testapp"/>
    <!--Name-->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:text="First Name Last Name"
        android:textSize="16dp"
        android:textColor="@color/blue_testapp"
        android:id="@+id/name_of_poster"
        android:layout_toRightOf="@id/profile_picture"
        />
    <!--Comment-->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:layout_marginTop="-5dp"
        android:text="This is a test comment"
        android:textSize="14dp"
        android:textColor="@color/black"
        android:id="@+id/comment"
        android:layout_below="@id/name_of_poster"
        android:layout_toRightOf="@id/profile_picture"/>
</RelativeLayout>

শিরোনাম

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="300dp"
        android:id="@+id/header_photo"
        android:layout_gravity="center_horizontal"/>
</LinearLayout>

অ্যাডাপ্টার কোড (আমাকে শুরু করার জন্য হিস্টারকে ধন্যবাদ):

public class CommentAdapter extends RecyclerView.Adapter<ViewHolder>{

    private final int rowCardLayout;
    public static Context mContext;
    private final int headerLayout;
    private final String [] comments;
    private static final int HEADER = 0;
    private static final int OTHER = 0;

    public CommentAdapter(int rowCardLayout, int headerLayout, Context context, String [] comments) {
        this.rowCardLayout = rowCardLayout;
        this.mContext = context;
        this.comments = comments;
        this.headerLayout = headerLayout;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        logger.i("onCreateViewHolder, viewtype: " + i); //viewtype always returns 0 so OTHER layout is never inflated
        if (i == HEADER) {
            View v = LayoutInflater.from(viewGroup.getContext()).inflate(headerLayout, viewGroup, false);
            return new ViewHolderHeader(v);
        }
        else if (i == OTHER){
            View v = LayoutInflater.from(viewGroup.getContext()).inflate(rowCardLayout, viewGroup, false);
            return new ViewHolderComments(v);
        }
        else 
          throw new RuntimeException("Could not inflate layout");
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        logger.i("onBindViewHolder, viewType: " + i);

        if (viewHolder instanceof ViewHolderComments)
            ((ViewHolderComments) viewHolder).comment.setText(comments[i].toString());
        if (viewHolder instanceof ViewHolderHeader)
           ((ViewHolderHeader) viewHolder).header.setImageResource(R.drawable.image2);
        else {
            logger.e("no instance of viewholder found");
        }
    }

    @Override
    public int getItemCount() {
        int count = comments.length + 1;
        logger.i("getItemCount: " + count);
        return count;
    }

    @Override
    public int getItemViewType(int position) {
        logger.i("getItemViewType position: " + position);
        if (position == HEADER)
            return HEADER;
        else
            return OTHER;
    }

    public static class ViewHolderComments extends RecyclerView.ViewHolder {
        public TextView comment;
        public ImageView image;

        public ViewHolderComments(View itemView) {
            super(itemView);
            comment = (TextView) itemView.findViewById(R.id.comment);
            image = (ImageView) itemView.findViewById(R.id.image);
        }
    }

    public static class ViewHolderHeader extends RecyclerView.ViewHolder {
        public final ImageView header;

        public ViewHolderHeader(View itemView){
            super(itemView);
            header = (ImageView) itemView.findViewById(R.id.header_photo);
        }
    }
}

উপরের কোড, শুধুমাত্র হেডার বিন্যাস viewType হিসেবে প্রদর্শিত ব্যবহার সবসময় 0. এটা দেখে মনে হচ্ছে কি এই । যদি আমি অন্য লেআউট জোর এটা দেখে মনে হচ্ছে এই :



এই প্রশ্নের সদৃশ হিসাবে এখানে , আমি আমার উত্তর, পোস্ট সেখানে :
SEB

একটি মার্জিত সমাধান: স্ট্যাকওভারফ্লো
প্রশ্নগুলি

উত্তর:


457

এর মতো সহজ উপায় নেই listview.addHeaderView()তবে আপনি শিরোলেখের জন্য আপনার অ্যাডাপ্টারে একটি প্রকার যোগ করে এটি অর্জন করতে পারেন।

এখানে একটি উদাহরণ

public class HeaderAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int TYPE_HEADER = 0;
    private static final int TYPE_ITEM = 1;
    String[] data;

    public HeaderAdapter(String[] data) {
        this.data = data;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_ITEM) {
            //inflate your layout and pass it to view holder
            return new VHItem(null);
        } else if (viewType == TYPE_HEADER) {
            //inflate your layout and pass it to view holder
            return new VHHeader(null);
        }

        throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof VHItem) {
            String dataItem = getItem(position);
            //cast holder to VHItem and set data
        } else if (holder instanceof VHHeader) {
            //cast holder to VHHeader and set data for header.
        }
    }

    @Override
    public int getItemCount() {
        return data.length + 1;
    }

    @Override
    public int getItemViewType(int position) {
        if (isPositionHeader(position))
            return TYPE_HEADER;

        return TYPE_ITEM;
    }

    private boolean isPositionHeader(int position) {
        return position == 0;
    }

    private String getItem(int position) {
        return data[position - 1];
    }

    class VHItem extends RecyclerView.ViewHolder {
        TextView title;

        public VHItem(View itemView) {
            super(itemView);
        }
    }

    class VHHeader extends RecyclerView.ViewHolder {
        Button button;

        public VHHeader(View itemView) {
            super(itemView);
        }
    }
}

সংক্ষেপে লিঙ্ক -> এখানে


2
সবকিছু ঠিক আছে বলে মনে হচ্ছে এবং এটি কাজ করা উচিত, তবে যাইহোক, পুনর্ব্যবহারকারী ভিউ MATCH_PARENT দেখুন কিছু পরিবর্তন হয়েছে কিনা তা দেখুন। এছাড়াও যদি এটি সম্ভব হয় তবে পুনর্ব্যাবসায়ীটিকে layout লেআউটের মূলটি দেখতে (পারফরম্যান্সের জন্য এটি ভাল)।
ইসি 84 বি 4

1
সান অফ বন্দুক, পুনর্ব্যবহারযোগ্য পরিস্কার করা এবং ম্যাচ পিতামাতাদের কাজ করা .... সাহায্যের জন্য অনেক ধন্যবাদ! আমি যত তাড়াতাড়ি সম্ভব আপনি upvote হবে।
ভিসিড্রয়েড

14
private String getItem(int position) { return data[position + 1]; }একটি এনপাই কারণ। যেহেতু শিরোনামের কারণে আমাদের অবস্থান এক দ্বারা বৃদ্ধি পেয়েছে, আমাদের ডেটা থেকে সঠিক আইটেমটি পেতে আমাদের 1 টি বিয়োগ করতে হয়েছে []। private String getItem(int position) { return data[position - 1]; }
টিম মালসিদ

2
যদি আপনার গ্রিডটি কেবল একটি সাধারণ গ্রিড হয় তবে কেবল লিনিয়ারলআউটআমনেজারটি ব্যবহার করুন এবং এক সারিতে আইটেমটি দেখান। এটির নামক বালতি সারি আমি দেখেছি গুগল তাদের কিছু অ্যাপে এটি ব্যবহার করে।
EC84B4

4
আপনি এই পদ্ধতির ব্যবহার করতে পারেন @nsL এবং অতিরিক্ত যোগ setSpanSizeLookupজন্য GridLayoutManager, তাই আপনার হেডার সকল কলাম নিতে হবে
দিমিত্রি Zaytsev

62

সহজ এবং পুনরায় ব্যবহারযোগ্য ItemDecoration

স্ট্যাটিক শিরোনামগুলি সহজেই একটি ItemDecorationএবং আরও কোনও পরিবর্তন ছাড়াই যুক্ত করা যায়

// add the decoration. done.
HeaderDecoration headerDecoration = new HeaderDecoration(/* init */);
recyclerView.addItemDecoration(headerDecoration);

অ্যাডাপ্টার বা একেবারে কোনও সংশোধন করার প্রয়োজন নেই বলে সজ্জাটিও পুনরায় ব্যবহারযোগ্য RecyclerView

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

শিরোনাম সজ্জা নমুনা

স্থির কেন ?

যদি আপনাকে কেবল পাঠ্য এবং চিত্রগুলি প্রদর্শন করতে হয় তবে এই সমাধানটি আপনার পক্ষে - ব্যবহারকারী বাটন বা প্যাজার দেখার মত ইন্টারঅ্যাকশন হওয়ার কোনও সম্ভাবনা নেই, কারণ এটি কেবল আপনার তালিকার শীর্ষে আঁকা হবে।

খালি তালিকার হ্যান্ডলিং

সাজানোর কোনও দৃষ্টিভঙ্গি না থাকলে সাজসজ্জা আঁকা হবে না। আপনাকে এখনও খালি তালিকা নিজেই পরিচালনা করতে হবে। (অ্যাডাপ্টারে একটি ডামি আইটেম যুক্ত করা একটি সম্ভাব্য কাজ হতে পারে))

কোড

আপনি এখানে গিটহাবের পুরো উত্স কোডটি ডেকরেটারের সূচনাতেBuilder সহায়তার জন্য, বা নীচের কোডটি ব্যবহার করে এবং নির্মাণকারীর কাছে আপনার নিজস্ব মান সরবরাহ করতে পারেন including

layout_heightআপনার দর্শন জন্য একটি সঠিক সেট করতে ভুলবেন না । যেমন match_parentসঠিকভাবে কাজ না করতে পারে।

public class HeaderDecoration extends RecyclerView.ItemDecoration {

    private final View mView;
    private final boolean mHorizontal;
    private final float mParallax;
    private final float mShadowSize;
    private final int mColumns;
    private final Paint mShadowPaint;

    public HeaderDecoration(View view, boolean scrollsHorizontally, float parallax, float shadowSize, int columns) {
        mView = view;
        mHorizontal = scrollsHorizontally;
        mParallax = parallax;
        mShadowSize = shadowSize;
        mColumns = columns;

        if (mShadowSize > 0) {
            mShadowPaint = new Paint();
            mShadowPaint.setShader(mHorizontal ?
                    new LinearGradient(mShadowSize, 0, 0, 0,
                            new int[]{Color.argb(55, 0, 0, 0), Color.argb(55, 0, 0, 0), Color.argb(3, 0, 0, 0)},
                            new float[]{0f, .5f, 1f},
                            Shader.TileMode.CLAMP) :
                    new LinearGradient(0, mShadowSize, 0, 0,
                            new int[]{Color.argb(55, 0, 0, 0), Color.argb(55, 0, 0, 0), Color.argb(3, 0, 0, 0)},
                            new float[]{0f, .5f, 1f},
                            Shader.TileMode.CLAMP));
        } else {
            mShadowPaint = null;
        }
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        // layout basically just gets drawn on the reserved space on top of the first view
        mView.layout(parent.getLeft(), 0, parent.getRight(), mView.getMeasuredHeight());

        for (int i = 0; i < parent.getChildCount(); i++) {
            View view = parent.getChildAt(i);
            if (parent.getChildAdapterPosition(view) == 0) {
                c.save();
                if (mHorizontal) {
                    c.clipRect(parent.getLeft(), parent.getTop(), view.getLeft(), parent.getBottom());
                    final int width = mView.getMeasuredWidth();
                    final float left = (view.getLeft() - width) * mParallax;
                    c.translate(left, 0);
                    mView.draw(c);
                    if (mShadowSize > 0) {
                        c.translate(view.getLeft() - left - mShadowSize, 0);
                        c.drawRect(parent.getLeft(), parent.getTop(), mShadowSize, parent.getBottom(), mShadowPaint);
                    }
                } else {
                    c.clipRect(parent.getLeft(), parent.getTop(), parent.getRight(), view.getTop());
                    final int height = mView.getMeasuredHeight();
                    final float top = (view.getTop() - height) * mParallax;
                    c.translate(0, top);
                    mView.draw(c);
                    if (mShadowSize > 0) {
                        c.translate(0, view.getTop() - top - mShadowSize);
                        c.drawRect(parent.getLeft(), parent.getTop(), parent.getRight(), mShadowSize, mShadowPaint);
                    }
                }
                c.restore();
                break;
            }
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (parent.getChildAdapterPosition(view) < mColumns) {
            if (mHorizontal) {
                if (mView.getMeasuredWidth() <= 0) {
                    mView.measure(View.MeasureSpec.makeMeasureSpec(parent.getMeasuredWidth(), View.MeasureSpec.AT_MOST),
                            View.MeasureSpec.makeMeasureSpec(parent.getMeasuredHeight(), View.MeasureSpec.AT_MOST));
                }
                outRect.set(mView.getMeasuredWidth(), 0, 0, 0);
            } else {
                if (mView.getMeasuredHeight() <= 0) {
                    mView.measure(View.MeasureSpec.makeMeasureSpec(parent.getMeasuredWidth(), View.MeasureSpec.AT_MOST),
                            View.MeasureSpec.makeMeasureSpec(parent.getMeasuredHeight(), View.MeasureSpec.AT_MOST));
                }
                outRect.set(0, mView.getMeasuredHeight(), 0, 0);
            }
        } else {
            outRect.setEmpty();
        }
    }
}

দয়া করে নোট করুন: গিটহাব প্রকল্পটি আমার ব্যক্তিগত খেলার মাঠ। এটি বৌদ্ধরূপে পরীক্ষা করা হয়নি, যে কারণে এখনও কোনও গ্রন্থাগার নেই

এটার কাজ কি?

একটি ItemDecorationতালিকার একটি আইটেম অতিরিক্ত অঙ্কন করা হয়। এই ক্ষেত্রে, প্রথম আইটেমের শীর্ষে একটি সজ্জা আঁকা হয়।

দৃশ্যটি পরিমাপ করা হয় এবং ছড়িয়ে দেওয়া হয়, তারপরে এটি প্রথম আইটেমের শীর্ষে টানা হয়। যদি একটি প্যারালাক্স প্রভাব যুক্ত করা হয় তবে এটি সঠিক সীমানায়ও ক্লিপ হবে।


1
একটি মার্জিত সমাধান দেখায়, তবে, আমার একটি প্রশ্ন রয়েছে: কখন আমি রিসাইক্লারভিউ.এডডি আইটেমডেকোরেশন কল করব?
ওয়েইবো

1
ধন্যবাদ, এটি ভাল কাজ করেছে! এই পদ্ধতিটি ব্যবহার করার একমাত্র অবক্ষয়টি হ'ল রিসাইক্লিউউতে আপনার কমপক্ষে 1 সারি থাকা দরকার।
ফিলিপ গিউলিয়ানী

3
হেডারের জন্য কীভাবে ক্লিকলিস্টেনার?
প্রশান্ত কেদিয়া

1
আমি নিম্নলিখিত ব্যতিক্রম পাচ্ছি: java.lang. নালপয়েন্টার এক্সেপশন: একটি নাল বস্তুর রেফারেন্সে ভার্চুয়াল পদ্ধতি 'বুলিয়ান android.support.v7.widget.RecyclerView $ ViewHolder.shouldIgnore ()' আহ্বান করার চেষ্টা
মাকালেলে

1
সজ্জায় ভিউগুলি অ্যাক্সেস করার কোনও উপায় আছে কি? আমি পাঠ্য গতিশীল সেট করতে চাই।
এসএমডিডি

44

আমার গ্রন্থাগারটি নির্দ্বিধায় ব্যবহার করুন, এখানে উপলভ্য ।

এটি আপনাকে যে Viewকোনও RecyclerViewব্যবহার করে LinearLayoutManagerবা GridLayoutManagerকেবল একটি সাধারণ পদ্ধতি কল দিয়ে শিরোনাম তৈরি করতে দেয় ।

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


কিভাবে হেডার উচ্চতা পরিবর্তন?
ইংসৌরভ

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

আপনি কি মনে করেন যে আপনি যে সমস্যাটি বর্ণনা করছেন তা এর সাথে সম্পর্কিত হতে পারে: github.com/blipinsk/RecyclerViewHeader/issues/16 ?
বারটেক লিপিনস্কি

লিপিনস্কি এই গ্রন্থাগারটি অবসর নিয়েছেন এবং পরিবর্তে এটি ব্যবহার করার পরামর্শ দিয়েছেন: github.com/Karumi/HeaderRecyclerView
Radley

1
আমি এই লাইব্রেরিটি নিখুঁতভাবে অবসর নিচ্ছি । আমি এটির জন্য এখনও একটি হালকা সমর্থন সরবরাহ করছি, তবে প্রকৃতপক্ষে আমি পরিবর্তে বিশেষায়িত অ্যাডাপ্টারের সাথে যাওয়ার পরামর্শ দিচ্ছি (যেমন করুমির একটি)।
বারটেক লিপিনস্কি

31

একটি পুনর্ব্যবহারযোগ্য দৃশ্যে আইটেমগুলি দিয়ে আপনাকে শিরোলেখ তৈরি করতে যাচ্ছি।শিরোনামের সাথে পুনর্ব্যবহারযোগ্য দৃশ্য

পদক্ষেপ 1- আপনার গ্রেড ফাইলের মধ্যে নির্ভরতা যুক্ত করুন।

compile 'com.android.support:recyclerview-v7:23.2.0'
// CardView
compile 'com.android.support:cardview-v7:23.2.0'

কার্ডভিউ সাজসজ্জার উদ্দেশ্যে ব্যবহৃত হয়।

পদক্ষেপ 2- তিনটি এক্সএমএল ফাইল তৈরি করুন। প্রধান ক্রিয়াকলাপের জন্য একটি Head দ্বিতীয় শিরোলেখ বিন্যাসের জন্য list তালিকার আইটেমের বিন্যাসের জন্য থ্রিল।

activity_main.xml

<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/my_recycler_view"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

header.xml

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

    <TextView
        android:id="@+id/txtHeader"
        android:gravity="center"
        android:textColor="#000000"
        android:textSize="@dimen/abc_text_size_large_material"
        android:background="#DCDCDC"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

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

list.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardElevation="1dp">

        <TextView
            android:id="@+id/txtName"
            android:text="abc"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

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

</LinearLayout>

পদক্ষেপ 3- তিনটি শিমের ক্লাস তৈরি করুন।

Header.java

public class Header extends ListItem {
    private String header;

    public String getHeader() {
        return header;
    }
    public void setHeader(String header) {
        this.header = header;
    }
}

ContentItem.java

public class ContentItem extends ListItem {

    private String name;
    private String rollnumber;

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    public String getRollnumber() {
        return rollnumber;
    }

    public void setRollnumber(String rollnumber) {
        this.rollnumber = rollnumber;
    }
}

ListItem.java

public class ListItem {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

পদক্ষেপ 4- MyRecyclerAdapter.java নামে একটি অ্যাডাপ্টার তৈরি করুন

public class MyRecyclerAdapter extends  RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int TYPE_HEADER = 0;
    private static final int TYPE_ITEM = 1;

    //Header header;
    List<ListItem> list;
    public MyRecyclerAdapter(List<ListItem> headerItems) {
        this.list = headerItems;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        if (viewType == TYPE_HEADER) {
            View v = inflater.inflate(R.layout.header, parent, false);
            return  new VHHeader(v);
        } else {
            View v = inflater.inflate(R.layout.list, parent, false);
            return new VHItem(v);
        }
        throw new IllegalArgumentException();
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof VHHeader) {
           // VHHeader VHheader = (VHHeader)holder;
            Header  currentItem = (Header) list.get(position);
            VHHeader VHheader = (VHHeader)holder;
            VHheader.txtTitle.setText(currentItem.getHeader());
        } else if (holder instanceof VHItem) 
            ContentItem currentItem = (ContentItem) list.get(position);
            VHItem VHitem = (VHItem)holder;
            VHitem.txtName.setText(currentItem.getName());
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (isPositionHeader(position))
            return TYPE_HEADER;
        return TYPE_ITEM;
    }

    private boolean isPositionHeader(int position) {
        return list.get(position) instanceof Header;
    }

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

    class VHHeader extends RecyclerView.ViewHolder{
        TextView txtTitle;
        public VHHeader(View itemView) {
            super(itemView);
            this.txtTitle = (TextView) itemView.findViewById(R.id.txtHeader);
        }
    }
    class VHItem extends RecyclerView.ViewHolder{
        TextView txtName;
        public VHItem(View itemView) {
            super(itemView);
            this.txtName = (TextView) itemView.findViewById(R.id.txtName);
        }
    }
}

পদক্ষেপ 5- মূলঅ্যাক্টিভিটিতে নিম্নলিখিত কোড যুক্ত করুন:

public class MainActivity extends AppCompatActivity {
    RecyclerView recyclerView;
    List<List<ListItem>> arraylist;
    MyRecyclerAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        adapter = new MyRecyclerAdapter(getList());
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(adapter);
    }

    private ArrayList<ListItem> getList() {
        ArrayList<ListItem> arrayList = new ArrayList<>();
        for(int j = 0; j <= 4; j++) {
            Header header = new Header();
            header.setHeader("header"+j);
            arrayList.add(header);
            for (int i = 0; i <= 3; i++) {
                ContentItem item = new ContentItem();
                item.setRollnumber(i + "");
                item.setName("A" + i);
                arrayList.add(item);
            }
        }
        return arrayList;
    }

}

ফাংশনটি getList () গতিশীলভাবে শিরোনাম এবং তালিকা আইটেমগুলির জন্য ডেটা তৈরি করছে।


একটি সেরা উত্তর। আমি এটিকে নেভিগেশনে ব্যবহার করেছি নেভিগেশন
সৌরভ ভান্ডারী

এটি একটি সহজ সাধারণ উত্তর - আমি সহজেই একটি তালিকা তালিকার মধ্যে 2 ডেটা আইটেম একত্রিত করার কৌশল সম্পর্কে ভাবতে পারি নি - উত্তরাধিকার এটিকে সহজ এবং অর্জনযোগ্য - দুহ!
ইউরা

8

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

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

1) একটি কাস্টম বিভাগ শ্রেণি তৈরি করুন:

class MySection extends StatelessSection {

    List<String> myList = Arrays.asList(new String[] {"Item1", "Item2", "Item3" });

    public MySection() {
        // call constructor with layout resources for this Section header, footer and items 
        super(R.layout.section_header, R.layout.section_footer,  R.layout.section_item);
    }

    @Override
    public int getContentItemsTotal() {
        return myList.size(); // number of items of this section
    }

    @Override
    public RecyclerView.ViewHolder getItemViewHolder(View view) {
        // return a custom instance of ViewHolder for the items of this section
        return new MyItemViewHolder(view);
    }

    @Override
    public void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position) {
        MyItemViewHolder itemHolder = (MyItemViewHolder) holder;

        // bind your view here
        itemHolder.tvItem.setText(myList.get(position));
    }
}

2) আইটেমগুলির জন্য একটি কাস্টম ভিউহোল্ডার তৈরি করুন:

class MyItemViewHolder extends RecyclerView.ViewHolder {

    private final TextView tvItem;

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

        tvItem = (TextView) itemView.findViewById(R.id.tvItem);
    }
}

3) সেকশনেড রেসাইক্লারভিউ অ্যাডাপ্টার সহ আপনার পুনর্বিবেচনাবিদ সেট আপ করুন

// Create an instance of SectionedRecyclerViewAdapter 
SectionedRecyclerViewAdapter sectionAdapter = new SectionedRecyclerViewAdapter();

MySection mySection = new MySection();

// Add your Sections
sectionAdapter.addSection(mySection);

// Set up your RecyclerView with the SectionedRecyclerViewAdapter
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(sectionAdapter);

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

6

আপনি কেবল একটি নেস্টডস্ক্রোলভিউতে আপনার শিরোনাম এবং আপনার পুনর্ব্যবহারযোগ্য ভিউ রাখতে পারেন:

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <include
            layout="@layout/your_header"/>

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

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>

স্ক্রোলিংটি সঠিকভাবে কাজ করার জন্য আপনাকে নিজের পুনর্ব্যবহারযোগ্য ভিউতে নেস্টেড স্ক্রোলিংটি অক্ষম করতে হবে:

myRecyclerView.setNestedScrollingEnabled(false);

3
বা অ্যান্ড্রয়েড ব্যবহার করুন: নেস্টডস্ক্রোলিংএনবলড = "মিথ্যা"
র‌্যাডলি

অ্যান্ড্রয়েড: নেস্টডস্ক্রোলিংএনবলড = "মিথ্যা" এর জন্য এপিআই লেভেল 21 দরকার যা সফল হয়। যাইহোক দুর্দান্ত সমাধান! একই আপনি অন্য পাদলেখ যোগ করতে হবে বা এমনকি দ্বিতীয় পুনর্ব্যবহারযোগ্য?
মাকালেলে

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

2
@ বিপুলকুমারের মন্তব্য সম্পূর্ণ সত্য। আপনি যখন অন্য স্ক্রোলভিউয়ের মধ্যে পুনর্ব্যবহার করেন তখন কোনও পুনর্ব্যবহারযোগ্য হবে না এবং এটি সমস্ত আইটেম তৈরি করবে।
ভোলকানসাহিন 45

আপনার আইটেমগুলি যদি রিসাইকেলারভিউতে 10 এর চেয়ে কম হয় তবে আপনি এটি করতে পারেন 😄
JIE ওয়াং

5

নেটিভ এপিআইতে এ জাতীয় "অ্যাডহাইডার" বৈশিষ্ট্য নেই, তবে "অ্যাড আইটেম" ধারণাটি রয়েছে।

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

এখানে তারা কীভাবে কাজ করে:

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

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

তাদের সম্পর্কে আরও অনেক কিছু বলার আছে, বিস্তারিত উইকি পৃষ্ঠাটি পড়তে ভাল ।

তাছাড়া FlexibleAdapter আপনি হেডার / বিভাগে তৈরি করার অনুমতি দেয়, এছাড়াও আপনি তাদের থাকতে পারে চটচটে এক লাইব্রেরিতে এবং অন্যদের দশ বিস্তারযোগ্য আইটেম, অবিরাম স্ক্রল, UI 'তে এক্সটেনশন ইত্যাদি মত বৈশিষ্ট্য ... সমস্ত!


4

এই পোস্টের উপর ভিত্তি করে , আমি রিসাইক্লার ভিউ.এডাপ্টারের একটি সাবক্লাস তৈরি করেছি যা একটি নির্বিচার সংখ্যক শিরোনাম এবং পাদচরণকে সমর্থন করে।

https://gist.github.com/mheras/0908873267def75dc746

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

আমি এখনও এটি পরীক্ষা করছি, তবে আপনি চাইলে এটি চেষ্টা করে দেখতে পারেন। আপনি যদি এটির সাথে কোনও সমস্যা পান তবে আমাকে জানান।


2

উপরে আরও একটি সমাধান রয়েছে যা উপরের সমস্ত ব্যবহারের কেসগুলি কভার করে: কম্পাউন্ডএডাপ্টার: https://github.com/negusoft/CompoundAdapter-android

আপনি এমন একটি অ্যাডাপ্টারগ্রুপ তৈরি করতে পারেন যা আপনার অ্যাডাপ্টারটিকে যেমন আছে তেমন ধরে রাখে, সাথে শিরোনামটি উপস্থাপনের জন্য একটি একক আইটেম সহ একটি অ্যাডাপ্টার। কোডটি সহজ এবং পঠনযোগ্য:

AdapterGroup adapterGroup = new AdapterGroup();
adapterGroup.addAdapter(SingleAdapter.create(R.layout.header));
adapterGroup.addAdapter(new CommentAdapter(...));

recyclerView.setAdapter(adapterGroup);

অ্যাডাপ্টারগ্রুপ বাসা বাঁধারও অনুমতি দেয়, সুতরাং বিভাগগুলি সহ একটি অ্যাডাপ্টারের জন্য, আপনি প্রতিটি বিভাগে অ্যাডাপ্টারগ্রুপ তৈরি করতে পারেন। তারপরে সমস্ত বিভাগগুলি একটি রুট অ্যাডাপ্টারগ্রুপে রাখুন।


1

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

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


বেস অ্যাডাপ্টারের সাথে একটি পুনর্ব্যবহারযোগ্য ভিউ ব্যবহার করে এমন কোনও উদাহরণ আপনি আমাকে দেখিয়ে দিতে পারেন? ধন্যবাদ!
ভিসিড্রয়েড

একটি তালিকায় শিরোলেখ / পাদলেখের জন্য সত্যিই একটি উল্লেখযোগ্য সুবিধা রয়েছে: আপনি এটিকে দৃশ্য থেকে বাইরে স্ক্রোল করতে পারেন। এই উদাহরণটি দেখুন যেখানে দৃশ্যমান সারিগুলির পরিমাণ প্রায় দ্বিগুণ হয়ে যাওয়ার সাথে সাথে পিনগিনগুলি বাইরে চলে আসবে , আমি এটি করার অন্য কোনও উপায় সম্পর্কে অবগত নই, তবে ListView.addHeaderViewবা এই প্রশ্নের উত্তর।
TWiStErRob

আমি ঠিক করি না বলে মনে করি না। যদি এটি অ্যাডাপ্টারের প্রথম আইটেম হয় তবে উদাহরণের মতো এটি কেন স্ক্রোল করতে পারে না?
ইজিগিত

2
আপনি বিজ্ঞপ্তি * পদ্ধতিগুলি ওভাররাইড করতে পারবেন না, কারণ এগুলি চূড়ান্ত হিসাবে চিহ্নিত হয়েছে।
মাটো

হুম আমি দুঃখিত তা চেক করিনি। পরিবর্তে, আপনি একটি অ্যাডাপ্টার মোড়ক তৈরি করতে পারেন যা মোড়ানো অ্যাডাপ্টারে একটি পর্যবেক্ষণযোগ্য যুক্ত করে এবং নিজের থেকে স্থানান্তরিত ইভেন্টগুলি প্রেরণ করে।
ইজিগিত

1
First - extends RecyclerView.Adapter<RecyclerView.ViewHolder>

public class MenuAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

এর পরে - পদ্ধতিটি আইটেম ভিউ টাইপ ওভাররাইড করুন *** আরও গুরুত্বপূর্ণ

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

ক্রিয়েটভিউহোল্ডার পদ্ধতি method

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.menu_item, parent, false);
    View header = LayoutInflater.from(parent.getContext()).inflate(R.layout.menu_header_item, parent, false);
    Log.d("onCreateViewHolder", String.valueOf(viewType));

    if (viewType == 0) {
        return new MenuLeftHeaderViewHolder(header, onClickListener);
    } else {
        return new MenuLeftViewHolder(view, onClickListener);
    }
}

বিন্ডভিউহোল্ডার পদ্ধতি method

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (position == 0) {
        MenuHeaderViewHolder menuHeaderViewHolder = (MenuHeaderViewHolder) holder;
        menuHeaderViewHolder.mTitle.setText(sMenuTitles[position]);
        menuHeaderViewHolder.mImage.setImageResource(sMenuImages[position]);
    } else {
        MenuViewHolder menuLeftViewHolder = (MenuLeftViewHolder) holder;
        menuViewHolder.mTitle.setText(sMenuTitles[position]);
        menuViewHolder.mImage.setImageResource(sMenuImages[position]);
    }
}

ফিনিস ইন ভিউহোল্ডার্স ক্লাস স্ট্যাটিক প্রয়োগ করে

public static class MenuViewHolder extends RecyclerView.ViewHolder 

public static class MenuLeftHeaderViewHolder extends RecyclerView.ViewHolder 

1

পুনর্ব্যবহারের জন্য এখানে কিছু আইটেম সজ্জা

public class HeaderItemDecoration extends RecyclerView.ItemDecoration {

private View customView;

public HeaderItemDecoration(View view) {
    this.customView = view;
}

@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
    super.onDraw(c, parent, state);
    customView.layout(parent.getLeft(), 0, parent.getRight(), customView.getMeasuredHeight());
    for (int i = 0; i < parent.getChildCount(); i++) {
        View view = parent.getChildAt(i);
        if (parent.getChildAdapterPosition(view) == 0) {
            c.save();
            final int height = customView.getMeasuredHeight();
            final int top = view.getTop() - height;
            c.translate(0, top);
            customView.draw(c);
            c.restore();
            break;
        }
    }
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    if (parent.getChildAdapterPosition(view) == 0) {
        customView.measure(View.MeasureSpec.makeMeasureSpec(parent.getMeasuredWidth(), View.MeasureSpec.AT_MOST),
                View.MeasureSpec.makeMeasureSpec(parent.getMeasuredHeight(), View.MeasureSpec.AT_MOST));
        outRect.set(0, customView.getMeasuredHeight(), 0, 0);
    } else {
        outRect.setEmpty();
    }
}
}      

1

আমি @ হিস্টার এর উপর ভিত্তি করে একটি বাস্তবায়ন করেছি আমার ব্যক্তিগত উদ্দেশ্যে একের করেছি, কিন্তু উত্তরাধিকার ব্যবহার করে।

আমি বাস্তবায়ন বিবরণ মেকানিজম লুকান (অ্যাড 1 মতো itemCount, থেকে বিয়োগ 1 positionএকটি বিমূর্ত সুপার ক্লাসে) HeadingableRecycleAdapterঅ্যাডাপ্টার থেকে মত প্রয়োজনীয় পদ্ধতি প্রয়োগ করে, onBindViewHolder, getItemViewTypeএবং getItemCount, উপার্জন যে পদ্ধতি চূড়ান্ত, এবং ক্লায়েন্ট লুকানো যুক্তিবিজ্ঞান সাথে নতুন পদ্ধতি উপলব্ধ করা হবে:

  • onAddViewHolder(RecyclerView.ViewHolder holder, int position),
  • onCreateViewHolder(ViewGroup parent),
  • itemCount()

এখানে HeadingableRecycleAdapterক্লাস এবং একটি ক্লায়েন্ট আছে। আমি হেডার লেআউটটি কিছুটা শক্ত কোডড রেখেছি কারণ এটি আমার প্রয়োজনের সাথে খাপ খায়।

public abstract class HeadingableRecycleAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final int HEADER_VIEW_TYPE = 0;

    @LayoutRes
    private int headerLayoutResource;
    private String headerTitle;
    private Context context;

    public HeadingableRecycleAdapter(@LayoutRes int headerLayoutResourceId, String headerTitle, Context context) {
        this.headerLayoutResource = headerLayoutResourceId;
        this.headerTitle = headerTitle;
        this.context = context;
    }

    public Context context() {
        return context;
    }

    @Override
    public final RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == HEADER_VIEW_TYPE) {
            return new HeaderViewHolder(LayoutInflater.from(context).inflate(headerLayoutResource, parent, false));
        }
        return onCreateViewHolder(parent);
    }

    @Override
    public final void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        int viewType = getItemViewType(position);
        if (viewType == HEADER_VIEW_TYPE) {
            HeaderViewHolder vh = (HeaderViewHolder) holder;
            vh.bind(headerTitle);
        } else {
            onAddViewHolder(holder, position - 1);
        }
    }

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

    @Override
    public final int getItemCount() {
        return itemCount() + 1;
    }

    public abstract int itemCount();

    public abstract RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent);

    public abstract void onAddViewHolder(RecyclerView.ViewHolder holder, int position);

}



@PerActivity
public class IngredientsAdapter extends HeadingableRecycleAdapter {
    public static final String TITLE = "Ingredients";
    private List<Ingredient> itemList;


    @Inject
    public IngredientsAdapter(Context context) {
        super(R.layout.layout_generic_recyclerview_cardified_header, TITLE, context);
    }

    public void setItemList(List<Ingredient> itemList) {
        this.itemList = itemList;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) {
        return new ViewHolder(LayoutInflater.from(context()).inflate(R.layout.item_ingredient, parent, false));
    }

    @Override
    public void onAddViewHolder(RecyclerView.ViewHolder holder, int position) {
        ViewHolder vh = (ViewHolder) holder;
        vh.bind(itemList.get(position));
    }

    @Override
    public int itemCount() {
        return itemList == null ? 0 : itemList.size();
    }

    private String getQuantityFormated(double quantity, String measure) {
        if (quantity == (long) quantity) {
            return String.format(Locale.US, "%s %s", String.valueOf(quantity), measure);
        } else {
            return String.format(Locale.US, "%.1f %s", quantity, measure);
        }
    }


    class ViewHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.text_ingredient)
        TextView txtIngredient;

        ViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        void bind(Ingredient ingredient) {
            String ingredientText = ingredient.getIngredient();
            txtIngredient.setText(String.format(Locale.US, "%s %s ", getQuantityFormated(ingredient.getQuantity(),
                    ingredient.getMeasure()), Character.toUpperCase(ingredientText.charAt(0)) +
                    ingredientText
                            .substring(1)));
        }
    }
}

1

হতে পারে একটি সমন্বয়কারী লেয়ারে শিরোনাম এবং পুনর্ব্যবহারযোগ্য জড়ান :

<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:elevation="0dp">

    <View
        android:id="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_scrollFlags="scroll" />

</android.support.design.widget.AppBarLayout>

<android.support.v7.widget.RecyclerView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />


এর সাথে সমস্যা হ'ল তালিকাটি স্ক্রিনের চেয়ে কম হলেও, এটি সর্বদা অ্যাপবারআলআউটের উচ্চতার জন্য স্ক্রোলিংয়ের অনুমতি দেবে। এখানে
বর্ণিত

0

সম্ভবত http://alexzh.com / টিউটোরিয়ালস / একাধিক- row- layouts- using- recyclerview/ সহায়তা করবে। এটি কেবল পুনর্ব্যবহারযোগ্য এবং কার্ডভিউ ব্যবহার করে। এখানে একটি অ্যাডাপ্টার রয়েছে:

public class DifferentRowAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private List<CityEvent> mList;
    public DifferentRowAdapter(List<CityEvent> list) {
        this.mList = list;
    }
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view;
        switch (viewType) {
            case CITY_TYPE:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_city, parent, false);
                return new CityViewHolder(view);
            case EVENT_TYPE:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_event, parent, false);
                return new EventViewHolder(view);
        }
        return null;
    }
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        CityEvent object = mList.get(position);
        if (object != null) {
            switch (object.getType()) {
                case CITY_TYPE:
                    ((CityViewHolder) holder).mTitle.setText(object.getName());
                    break;
                case EVENT_TYPE:
                    ((EventViewHolder) holder).mTitle.setText(object.getName());
                    ((EventViewHolder) holder).mDescription.setText(object.getDescription());
                    break;
            }
        }
    }
    @Override
    public int getItemCount() {
        if (mList == null)
            return 0;
        return mList.size();
    }
    @Override
    public int getItemViewType(int position) {
        if (mList != null) {
            CityEvent object = mList.get(position);
            if (object != null) {
                return object.getType();
            }
        }
        return 0;
    }
    public static class CityViewHolder extends RecyclerView.ViewHolder {
        private TextView mTitle;
        public CityViewHolder(View itemView) {
            super(itemView);
            mTitle = (TextView) itemView.findViewById(R.id.titleTextView);
        }
    }
    public static class EventViewHolder extends RecyclerView.ViewHolder {
        private TextView mTitle;
        private TextView mDescription;
        public EventViewHolder(View itemView) {
            super(itemView);
            mTitle = (TextView) itemView.findViewById(R.id.titleTextView);
            mDescription = (TextView) itemView.findViewById(R.id.descriptionTextView);
        }
    }
}

এবং এখানে একটি সত্তা:

public class CityEvent {
    public static final int CITY_TYPE = 0;
    public static final int EVENT_TYPE = 1;
    private String mName;
    private String mDescription;
    private int mType;
    public CityEvent(String name, String description, int type) {
        this.mName = name;
        this.mDescription = description;
        this.mType = type;
    }
    public String getName() {
        return mName;
    }
    public void setName(String name) {
        this.mName = name;
    }
    public String getDescription() {
        return mDescription;
    }
    public void setDescription(String description) {
        this.mDescription = description;
    }
    public int getType() {
        return mType;
    }
    public void setType(int type) {
        this.mType = type;
    }
}

0

আপনি addHeaderView তৈরি করতে এবং ব্যবহার করতে পারেন

adapter.addHeaderView(View)

এই কোডটি addHeaderViewআরও একবারে একটি শিরোলেখ তৈরি করে। শিরোনামগুলির উচিত:

android:layout_height="wrap_content"

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int TYPE_ITEM = -1;
    public class MyViewSHolder extends RecyclerView.ViewHolder {
        public MyViewSHolder (View view) {
            super(view);
        }
        // put you code. for example:
        View mView;
        ...
    }

    public class ViewHeader extends RecyclerView.ViewHolder {
        public ViewHeader(View view) {
            super(view);
        }
    }

    private List<View> mHeaderViews = new ArrayList<>();
    public void addHeaderView(View headerView) {
        mHeaderViews.add(headerView);
    }

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

    @Override
    public int getItemViewType(int position) {
        if (mHeaderViews.size() > position) {
            return position;
        }

        return TYPE_ITEM;
    }
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType != TYPE_ITEM) {
            //inflate your layout and pass it to view holder
            return new ViewHeader(mHeaderViews.get(viewType));
        }
        ...
    }
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int basePosition1) {
        if (holder instanceof ViewHeader) {
            return;
        }
        int basePosition = basePosition1 -  mHeaderViews.size();
        ...
    }
}

0

কয়েক বছর হয়ে গেছে, তবে যে কেউ পরে এটি পড়ছে ...

উপরের কোডটি ব্যবহার করে, ভিউটাইপ সর্বদা 0 হিসাবে কেবল শিরোনাম বিন্যাস প্রদর্শিত হয়।

সমস্যাটি স্থির ঘোষণার মধ্যে রয়েছে:

private static final int HEADER = 0;
private static final int OTHER = 0;  <== bug 

আপনি যদি উভয়কে শূন্য হিসাবে ঘোষণা করেন তবে আপনি সর্বদা শূন্য পাবেন!


0

আমি ইসি 84 বি 4 উত্তর দ্বারা প্রস্তাবিত একই পদ্ধতির বাস্তবায়ন করেছি , তবে আমি রিসাইক্ল ভিউ অ্যাডাপ্টারটিকে বিমূর্ত করেছি এবং ইন্টারফেসের মাধ্যমে এটিকে সহজেই পুনরায় পরিবর্তনযোগ্য করে তুলেছি।

সুতরাং আমার পদ্ধতির ব্যবহারের জন্য আপনার প্রকল্পে নিম্নলিখিত বেস ক্লাস এবং ইন্টারফেস যুক্ত করা উচিত:

1) ইন্টারফেস যা অ্যাডাপ্টারের জন্য ডেটা সরবরাহ করে (জেনেরিক টাইপ টি সংগ্রহ, এবং জেনেরিক টাইপ পি এর অতিরিক্ত পরামিতি (যদি প্রয়োজন হয়))

public interface IRecycleViewListHolder<T,P>{
            P getAdapterParameters();
            T getItem(int position);
            int getSize();
    }

2) আপনার আইটেমগুলি বাঁধার জন্য কারখানা (শিরোনাম / আইটেম):

public interface IViewHolderBinderFactory<T,P> {
        void bindView(RecyclerView.ViewHolder holder, int position,IRecycleViewListHolder<T,P> dataHolder);
}

3) ভিউহোল্ডারগুলির জন্য কারখানা (শিরোনাম / আইটেম):

public interface IViewHolderFactory {
    RecyclerView.ViewHolder provideInflatedViewHolder(int viewType, LayoutInflater layoutInflater,@NonNull ViewGroup parent);
}

4) শিরোলেখ সহ অ্যাডাপ্টারের জন্য বেস শ্রেণি:

public class RecycleViewHeaderBased<T,P> extends RecyclerView.Adapter<RecyclerView.ViewHolder>{

    public final static int HEADER_TYPE = 1;
    public final static int ITEM_TYPE = 0;
    private final IRecycleViewListHolder<T, P> dataHolder;
    private final IViewHolderBinderFactory<T,P> binderFactory;
    private final IViewHolderFactory viewHolderFactory;

    public RecycleViewHeaderBased(IRecycleViewListHolder<T,P> dataHolder, IViewHolderBinderFactory<T,P> binderFactory, IViewHolderFactory viewHolderFactory) {
        this.dataHolder = dataHolder;
        this.binderFactory = binderFactory;
        this.viewHolderFactory = viewHolderFactory;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        return viewHolderFactory.provideInflatedViewHolder(viewType,layoutInflater,parent);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
            binderFactory.bindView(holder, position,dataHolder);
    }

    @Override
    public int getItemViewType(int position) {
        if(position == 0)
            return HEADER_TYPE;
        return ITEM_TYPE;
    }

    @Override
    public int getItemCount() {
        return dataHolder.getSize()+1;
    }
}

ব্যবহারের উদাহরণ :

1) IRecycleViewListHolder বাস্তবায়ন:

public class AssetTaskListData implements IRecycleViewListHolder<Map.Entry<Integer, Integer>, GroupedRecord> {
    private List<Map.Entry<Integer, Integer>> assetCountList;
    private GroupedRecord record;

    public AssetTaskListData(Map<Integer, Integer> assetCountListSrc, GroupedRecord record) {
        this.assetCountList =  new ArrayList<>();
        for(Object  entry: assetCountListSrc.entrySet().toArray()){
            Map.Entry<Integer,Integer> entryTyped = (Map.Entry<Integer,Integer>)entry;
            assetCountList.add(entryTyped);
        }
        this.record = record;
    }

    @Override
    public GroupedRecord getAdapterParameters() {
        return record;
    }

    @Override
    public Map.Entry<Integer, Integer> getItem(int position) {
        return assetCountList.get(position-1);
    }

    @Override
    public int getSize() {
        return assetCountList.size();
    }
}

2) আইভিউহোল্ডারবাইন্ডার ফ্যাক্টরি বাস্তবায়ন:

public class AssetTaskListBinderFactory implements IViewHolderBinderFactory<Map.Entry<Integer, Integer>, GroupedRecord> {
    @Override
    public void bindView(RecyclerView.ViewHolder holder, int position, IRecycleViewListHolder<Map.Entry<Integer, Integer>, GroupedRecord> dataHolder) {
        if (holder instanceof AssetItemViewHolder) {
            Integer assetId = dataHolder.getItem(position).getKey();
            Integer assetCount = dataHolder.getItem(position).getValue();
            ((AssetItemViewHolder) holder).bindItem(dataHolder.getAdapterParameters().getRecordId(), assetId, assetCount);
        } else {
            ((AssetHeaderViewHolder) holder).bindItem(dataHolder.getAdapterParameters());
        }
    }
}

3) আইভিউহোল্ডারফ্যাক্টরি বাস্তবায়ন:

public class AssetTaskListViewHolderFactory implements IViewHolderFactory {
    private IPropertyTypeIconMapper iconMapper;
    private ITypeCaster caster;

    public AssetTaskListViewHolderFactory(IPropertyTypeIconMapper iconMapper, ITypeCaster caster) {
        this.iconMapper = iconMapper;
        this.caster = caster;
    }

    @Override
    public RecyclerView.ViewHolder provideInflatedViewHolder(int viewType, LayoutInflater layoutInflater, @NonNull ViewGroup parent) {
        if (viewType == RecycleViewHeaderBased.HEADER_TYPE) {
            AssetBasedHeaderItemBinding item = DataBindingUtil.inflate(layoutInflater, R.layout.asset_based_header_item, parent, false);
            return new AssetHeaderViewHolder(item.getRoot(), item, caster);
        }
        AssetBasedListItemBinding item = DataBindingUtil.inflate(layoutInflater, R.layout.asset_based_list_item, parent, false);
        return new AssetItemViewHolder(item.getRoot(), item, iconMapper, parent.getContext());
    }
}

4) ডেরাইভিং অ্যাডাপ্টার

public class AssetHeaderTaskListAdapter extends RecycleViewHeaderBased<Map.Entry<Integer, Integer>, GroupedRecord> {
   public AssetHeaderTaskListAdapter(IRecycleViewListHolder<Map.Entry<Integer, Integer>, GroupedRecord> dataHolder,
                                      IViewHolderBinderFactory binderFactory,
                                      IViewHolderFactory viewHolderFactory) {
        super(dataHolder, binderFactory, viewHolderFactory);
    }
}

5) অ্যাডাপ্টারের ক্লাস ইনস্ট্যান্ট করুন:

private void setUpAdapter() {
        Map<Integer, Integer> objectTypesCountForGroupedTask = groupedTaskRepository.getObjectTypesCountForGroupedTask(this.groupedRecordId);
        AssetTaskListData assetTaskListData = new AssetTaskListData(objectTypesCountForGroupedTask, getGroupedRecord());
        adapter = new AssetHeaderTaskListAdapter(assetTaskListData,new AssetTaskListBinderFactory(),new AssetTaskListViewHolderFactory(iconMapper,caster));
        assetTaskListRecycler.setAdapter(adapter);
    }

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.