آموزش View شناور برای RecyclerView در اندروید

امتیاز 2.00 ( 1 رای )

سلام دوستان امیدوارم حالتان خوب باشد در این سری از آموزش برنامه نویسی اندروید به آموزش View شناور برای RecyclerView در اندروید می پردازیم این View شناور در بخش Contact یا همان مخاطبین تلفن از اندروید 5 به بالا وجود دارد در ادامه می توانید پیش نمایشی از آن را مشاهده کنید با ما همراه باشید.
 

 
ابتدا برای اینکه از این کتاب خانه استفاده کنیم باید
وارد فایل Build.gradle از نوع Module شده سپس در بخش dependencies خط زیر را اضافه کنید.

compile 'com.gvillani:pinnedlist:0.9.2'

پروژه را sync کنید.
در این آموزش از کتاب خانه Design گوگل و RecyclerView  نیز استفاده شده است پس در همان فایل بالا خط های زیر را نیز قرار دهید.

compile 'com.android.support:design:22.2.0'
compile 'com.android.support:recyclerview-v7:22.2.0'

پروژه را sync کنید.
ابتدا یک فایل به نام item_contact.xml در layout ایجاد کرده و کدهای زیر را در آن قرار دهید.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="6dp">
    <ir.programchi.RoundedImageView
        android:id="@+id/photo"
        android:layout_width="56dp"
        android:layout_height="56dp"/>
    <TextView
        android:id="@+id/name"
        android:textColor="#EE040404"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="6dp"/>
    <TextView
        android:id="@+id/surname"
        android:textColor="#EE040404"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="6dp"/>
</LinearLayout>

در بالا باید به جای ir.programchi نام پکیج خودتان را قرار دهید (شاید خطا داشته باشید تا پایان آموزش رفته می بینید که خطاها از بین می روند ) کد بالا شکل ظاهری آیتم ها را ایجاد می کند (بعدا این لایه Inflate می شود در layout اصلی)
سپس یک layout به نام activity_text_demo.xml ایجاد کرده ( این layout اصلی ما است ) و کدهای زیر را در آن قرار دهید.

<?xml version="1.0" encoding="utf-8"?>
<com.gvillani.pinnedlist.PinnedListLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/pinned_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:fade_effect="true"
    app:pin_text_color="@color/colorAccent"
    app:pin_text_size="30sp"
    app:pin_vertical_position="top"
    app:type="text">
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    </android.support.design.widget.AppBarLayout>
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="16dp" />
</com.gvillani.pinnedlist.PinnedListLayout>

بخش مهم کد بالا PinnedListLayout که استفاده شده است.
یک فایل جاوا به نام RoundedImageView.java ایجاد کرده و کدهای زیر را در آن قرار دهید.

package ir.programchi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
 * Created by Jefferson on 09/04/2016.
 */
public class RoundedImageView extends ImageView {
    public RoundedImageView(Context context) {
        super(context);
    }
    public RoundedImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        Drawable drawable = getDrawable();
        if (drawable == null) {
            return;
        }
        if (getWidth() == 0 || getHeight() == 0) {
            return;
        }
        Bitmap b = ((BitmapDrawable) drawable).getBitmap();
        Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
        int w = getWidth(), h = getHeight();
        Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
        canvas.drawBitmap(roundBitmap, 0, 0, null);
    }
    public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
        Bitmap sbmp;
        if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
            float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
            float factor = smallest / radius;
            sbmp = Bitmap.createScaledBitmap(bmp, (int) (bmp.getWidth() / factor), (int) (bmp.getHeight() / factor), false);
        } else {
            sbmp = bmp;
        }
        Bitmap output = Bitmap.createBitmap(radius, radius,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final int color = 0xffa19774;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, radius, radius);
        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setDither(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(Color.parseColor("#BAB399"));
        canvas.drawCircle(radius / 2 + 0.7f,
                radius / 2 + 0.7f, radius / 2 + 0.1f, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(sbmp, rect, rect, paint);
        return output;
    }
}

کد بالا عکس گرد ایجاد می کند قبلا این کلاس را توضیح داده بودیم برای اینکه به آموزش آن دسترسی داشته باشید از لینک زیر استفاده کنید.

آموزش ساخت عکس گرد در اندروید

قبل از اینکه به ادامه برنامه برسیم باید یک فایل را دانلود کنید این فایل شامل عکس هایی که در برنامه استفاده شده است بعد از دانلود تمامی عکس ها را در پوشه drawable قرار دهید.
لینک دانلود
یک فایل جاوا به نام Contact.java ایجاد کرده و کدهای زیر را در آن قرار دهید.

package ir.programchi;
import com.gvillani.pinnedlist.GroupListWrapper;
/**
 * Created by Jefferson on 09/04/2016.
 */
public class Contact implements GroupListWrapper.Selector{
    private String name;
    private String surname;
    private Integer photo;
    public Contact(String name, String surname, Integer photo) {
        this.name = name;
        this.surname = surname;
        this.photo = photo;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getPhoto() {
        return photo;
    }
    public void setPhoto(Integer photo) {
        this.photo = photo;
    }
    @Override
    public String toString() {
        return "Contact{" +
                "name='" + name + '\'' +
                ", surname='" + surname + '\'' +
                ", photo=" + photo +
                '}';
    }
    @Override
    public String select() {
        return getName()+getSurname();
    }
    public String getSurname() {
        return surname;
    }
    public void setSurname(String surname) {
        this.surname = surname;
    }
}

کلاس بالا همان getter و setter ما است.
چون item سفارشی ایجاد کردیم باید آداپتور سفارشی نیز ایجاد کنیم برای اینکار یک فایل جاوا به نام ContactAdapter.java ایجاد کرده و کدهای زیر را در آن قرار دهید.

package ir.programchi;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.gvillani.pinnedlist.GroupListWrapper;
import com.gvillani.pinnedlist.PinnedAdapter;
import com.gvillani.pinnedlist.PinnedListLayout;
import com.gvillani.pinnedlist.PinnedViewHolder;
/**
 * Created by Jefferson on 09/04/2016.
 */
public class ContactAdapter extends PinnedAdapter {
    private final LayoutInflater mLayoutInflater;
    public ContactAdapter(Context context, GroupListWrapper listGroup, PinnedListLayout layout) {
        super(listGroup, layout);
        mLayoutInflater = LayoutInflater.from(context);
    }
    @Override
    public PinnedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mLayoutInflater.inflate(R.layout.item_contact, parent, false);
        PinnedViewHolder pinnedViewHolder = new ViewHolderContact(getRowLayout(view));
        return pinnedViewHolder;
    }
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        super.onBindViewHolder(holder, position);
        final Contact contact = (Contact) mListWrapper.getItem(position);
        ((ViewHolderContact) holder).tvName.setText(contact.getName());
        ((ViewHolderContact) holder).tvSurname.setText(contact.getSurname());
        ((ViewHolderContact) holder).ivPhoto.setImageResource(contact.getPhoto());
    }
    static class ViewHolderContact extends PinnedViewHolder {
        private RoundedImageView ivPhoto;
        private TextView tvName;
        private TextView tvSurname;
        public ViewHolderContact(View rowLayout) {
            super(rowLayout);
            ivPhoto = (RoundedImageView) rowLayout.findViewById(R.id.photo);
            tvName = (TextView) rowLayout.findViewById(R.id.name);
            tvSurname = (TextView) rowLayout.findViewById(R.id.surname);
        }
    }
}

کد بالا layout که در اول ایجاد کردیم را Inflate می کند.
و در آخر در اکتیویتی اصلی که نام آن برابر با DemoTextActivity.java است کدهای زیر را قرار میدهیم.

package ir.programchi;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import com.gvillani.pinnedlist.GroupListWrapper;
import com.gvillani.pinnedlist.PinnedListLayout;
import java.util.ArrayList;
import java.util.List;
/**
 * Created by Jefferson on 19/04/2016.
 */
public class DemoTextActivity extends AppCompatActivity {
    private PinnedListLayout mPinnedListLayout;
    private RecyclerView.Adapter mListAdapter;
    private RecyclerView mRecyclerView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_text_demo);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        initLayout();
        findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "CoordinatorLayout still works! :)", Snackbar.LENGTH_LONG).show();
            }
        });
    }
    private void initLayout() {
        mPinnedListLayout = (PinnedListLayout) findViewById(R.id.pinned_layout);
        mRecyclerView = mPinnedListLayout.getRecyclerView();
        Contact c1 = new Contact("Ben", "Weber", R.drawable.contact1);
        Contact c2 = new Contact("Emma", "Hartmann", R.drawable.contact9);
        Contact c3 = new Contact("Gustav", "Eriksson", R.drawable.contact7);
        Contact c4 = new Contact("Lucas", "Nillson", R.drawable.contact4);
        Contact c5 = new Contact("Maia", "Andersson", R.drawable.contact11);
        Contact c6 = new Contact("Oscar", "Karlsson", R.drawable.contact6);
        Contact c7 = new Contact("Williams", "Johansson", R.drawable.contact5);
        Contact c8 = new Contact("Jayden", "De Jong", R.drawable.contact4);
        Contact c9 = new Contact("Julia", "Meijer", R.drawable.contact11);
        Contact c10 = new Contact("Lieke", "Visser", R.drawable.contact2);
        Contact c11 = new Contact("Luuk", "Tassi", R.drawable.contact3);
        Contact c12 = new Contact("Sam", "Van den Berg", R.drawable.contact1);
        Contact c13 = new Contact("Stijn", "De Vries", R.drawable.contact6);
        Contact c14 = new Contact("Thomas", "Van Dijk", R.drawable.contact5);
        Contact c15 = new Contact("Franco", "Bianchi", R.drawable.contact3);
        Contact c16 = new Contact("Giuseppe", "Villani", R.drawable.me);
        Contact c17 = new Contact("Lisa", "Verdi", R.drawable.contact9);
        Contact c18 = new Contact("Maria", "Rossi", R.drawable.contact10);
        Contact c19 = new Contact("Leonor", "Santos", R.drawable.contact9);
        Contact c20 = new Contact("Santiago", "Ferreira", R.drawable.contact1);
        Contact c21 = new Contact("Maria", "Pereira", R.drawable.contact9);
        Contact c22 = new Contact("Francisco", "Sousa", R.drawable.contact4);
        Contact c23 = new Contact("Rodrigo", "Martins", R.drawable.contact5);
        Contact c24 = new Contact("Duarte", "Gomes", R.drawable.contact6);
        Contact c25 = new Contact("Lucia", "Garcia", R.drawable.contact9);
        Contact c26 = new Contact("Pedro", "Fernandez", R.drawable.contact1);
        Contact c27 = new Contact("Daniela", "Gonzales", R.drawable.contact9);
        Contact c28 = new Contact("Alvaro", "Perez", R.drawable.contact7);
        Contact c29 = new Contact("David", "Martin", R.drawable.contact3);
        Contact c30 = new Contact("Camille", "Bernard", R.drawable.contact9);
        Contact c31 = new Contact("Louis", "Robert", R.drawable.contact1);
        Contact c32 = new Contact("Jules", "Petit", R.drawable.contact4);
        Contact c33 = new Contact("Daniel", "Kimani", R.drawable.contact8);
        Contact c34 = new Contact("Faith", "Mwangi", R.drawable.contact9);
        Contact c35 = new Contact("Jamesohn", "Kamau", R.drawable.contact1);
        Contact c36 = new Contact("Jonson", "Kariuki", R.drawable.contact3);
        Contact c37 = new Contact("Victor", "Ochieng", R.drawable.contact6);
        Contact c38 = new Contact("Aziza", "Elzarak", R.drawable.contact9);
        Contact c39 = new Contact("Youssef", "Jamil", R.drawable.contact1);
        Contact c40 = new Contact("Bob", "Miller", R.drawable.contact4);
        Contact c41 = new Contact("Carl", "Mayer", R.drawable.contact6);
        Contact c42 = new Contact("Bill", "Carson", R.drawable.contact5);
        Contact c43 = new Contact("Thom", "Sayer", R.drawable.contact1);
        Contact c44 = new Contact("Jim", "Hall", R.drawable.contact6);
        Contact c45 = new Contact("Paul", "Stroustrup", R.drawable.contact3);
        List<GroupListWrapper.Selector> contacts = new ArrayList<>();
        contacts.add(c1);
        contacts.add(c2);
        contacts.add(c3);
        contacts.add(c4);
        contacts.add(c5);
        contacts.add(c6);
        contacts.add(c7);
        contacts.add(c8);
        contacts.add(c9);
        contacts.add(c10);
        contacts.add(c11);
        contacts.add(c12);
        contacts.add(c13);
        contacts.add(c14);
        contacts.add(c15);
        contacts.add(c16);
        contacts.add(c17);
        contacts.add(c18);
        contacts.add(c19);
        contacts.add(c20);
        contacts.add(c21);
        contacts.add(c22);
        contacts.add(c23);
        contacts.add(c24);
        contacts.add(c25);
        contacts.add(c26);
        contacts.add(c27);
        contacts.add(c28);
        contacts.add(c29);
        contacts.add(c30);
        contacts.add(c31);
        contacts.add(c32);
        contacts.add(c33);
        contacts.add(c34);
        contacts.add(c35);
        contacts.add(c36);
        contacts.add(c37);
        contacts.add(c38);
        contacts.add(c39);
        contacts.add(c40);
        contacts.add(c41);
        contacts.add(c42);
        contacts.add(c43);
        contacts.add(c44);
        contacts.add(c45);
        GroupListWrapper listGroup = GroupListWrapper.createAlphabeticList(contacts, GroupListWrapper.ASCENDING);
        mListAdapter = new ContactAdapter(this, listGroup, mPinnedListLayout);
        mRecyclerView.setAdapter(mListAdapter);
    }
}

کد بالا کمی طولانی است ولی چیز خاصی ندارد ابتدا int مربوط به عکس ها به دست آمده سپس یک آرایه از داده های sample که می خواهیم در برنامه قرار گیرد ایجاد کرده سپس در RecyclerView قرار می گیرد اگر کنار هر سری از کاربران را ببیند یک کلمه (Label) نمایش داده می شود پشتیبانی فارسی آن تست نشده است خودتان تست کنید.
 
این آموزش هم به پایان رسید.
 
موفق و موید باشید.

مطالعه بیشتر