1. 程式人生 > >Android使用兩種方式實現類似三隻松鼠首頁圖片滑動居中效果

Android使用兩種方式實現類似三隻松鼠首頁圖片滑動居中效果

       昨天做商城專案第2版,UI給出一個了設計圖,商品圖片可以左右滑動對齊,剛開始以為一個Recyclerview加個方向滑動一下就搞定了,做出來後UI說效果不對,參考三隻松鼠商城首頁效果,研究了一下,效果就是每次不管左滑還是右滑圖片都是處於居中位置的,使用了Gallery類似照片牆實現,後來看到Recyclerview有一個輔助類SnapHelper也可以實現.Gallery和Recyclerview這兩種方式都可以實現,小夥伴們可以看個人愛好選擇其中一種即可.

Android Gallery控制元件的主要功能就是實現圖片的瀏覽,

android:spacing setSpacing(int)  (設定間距)

android:animationDuration setAnimationDuration(int)(設定動畫速度)

RecyclerView在24.2.0版本中新增了SnapHelper這個輔助類,用於輔助RecyclerView在滾動結束時將專案對齊到某個位置。特別是列表橫向滑動時,很多時候不會讓列表滑到任意位置,而是會有一定的規則限制,這時候就可以通過SnapHelper來定義對齊規則了。

三隻松鼠的效果截圖如下:(由於動圖比較大,就放靜態的,想看具體效果的可以下載三隻松鼠App檢視即可)

1.Gallery 實現方式程式碼如下:

GalleryActivity類程式碼:

**
 * 作者: njb
 * 時間: 2018/10/19 0019-上午 11:08
 * 描述: Gallery實現圖片滑動居中對齊
 * 來源:
 */
public class GalleryActivity extends BaseActivity {
    private Gallery myGallery;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_gallery);
        //初始化檢視
        initView();
        //初始化Adapter
        initGalleryAdapter();
    }

    /**
     * 初始化檢視
     */
    private void initView() {
        myGallery = findViewById(R.id.myGallery);
    }

    /**
     * 初始化Adapter
     */
    private void initGalleryAdapter() {
        setTitle("電影海報");
        MyGalleryAdapter galAdapter = new MyGalleryAdapter(App.getContext());
        myGallery.setAdapter(galAdapter);
        //點選監聽
        myGallery.setOnItemClickListener(new OnItemClickListenerImpl());
    }

    private class OnItemClickListenerImpl implements AdapterView.OnItemClickListener {
        public void onItemClick(AdapterView<?> parent, View view, int position,
                                long id) {
            Toast.makeText(GalleryActivity.this, String.valueOf(position),
                    Toast.LENGTH_SHORT).show();
        }
    }

}

介面佈局程式碼:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:orientation="vertical">

    <Gallery
        android:id="@+id/myGallery"
        android:layout_width="match_parent"
        android:layout_height="500dp"
        android:gravity="center_vertical"
        android:spacing="8dp"//設定間距
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
MyGalleryAdapter類程式碼: 
/**
 * 作者: njb
 * 時間: 2018/10/19 0019-上午 11:21
 * 描述: gallery介面卡
 * 來源:
 */
public class MyGalleryAdapter extends BaseAdapter {
    private Context context;
    private Integer[] images = { R.mipmap.image1, R.mipmap.image2,
            R.mipmap.image3,R.mipmap.image4,R.mipmap.image5,R.mipmap.image6, R.mipmap.image7,
            R.mipmap.image8,R.mipmap.image10,R.mipmap.image11,R.mipmap.image12,R.mipmap.cat_3};

    public MyGalleryAdapter(Context c) {
        context = c;
    }

    public int getCount() {
        return images.length;
    }

    public Object getItem(int position) {
        return images[position];
    }

    public long getItemId(int position) {
        return images[position];
    }

    @SuppressLint("ClickableViewAccessibility")
    public View getView(int position, View convertView, ViewGroup parent) {
        final ImageView imageview = new ImageView(context);
        //圖片自適應大小
/*                imageview.setLayoutParams(new Gallery.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT));*/
        //設定圖片大小為螢幕寬高,其中寬度為0.8
        int width = context.getResources().getDisplayMetrics().widthPixels;
        int height= context.getResources().getDisplayMetrics().heightPixels;
        imageview.setLayoutParams(new Gallery.LayoutParams((int)(width*0.8f), height));
        //設定圖片的縮放模式
        imageview.setScaleType(ImageView.ScaleType.FIT_CENTER);
        imageview.setImageResource(images[position]);

        final int pos = position;

        //觸控galley的image的時候
        imageview.setOnTouchListener(new View.OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event) {

                imageview.setScaleType(ImageView.ScaleType.CENTER);
                imageview.setImageResource(images[pos]);

                return false;
            }
        });
        return imageview;
    }
}
Gallery實現效果截圖如下:

2.RecyclerView方式程式碼如下:

/**
 * 作者: njb
 * 時間: 2018/10/19 0019-下午 5:15
 * 描述: 圖片滑動居中的recyclerView
 * 來源:
 */
public class SnapRecyclerViewActivity extends BaseActivity {
    private RecyclerView rvStart,rvCenter,rvTop;
    private List<FeatureModel> modelList;
    private SnapAdapter snapAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_center_recyclerview);
        //初始化檢視
        initView();
        //初始化資料
        initData();
        //初始化Adapter
        initSnaAdapter();
    }

    /**
     * 初始化檢視
     */
    private void initView() {
        rvStart= findViewById(R.id.rv_start);
        rvCenter= findViewById(R.id.rv_center);
        rvTop= findViewById(R.id.rv_top);
    }

    /**
     * 初始化資料
     */
    private void initData() {
        modelList = new ArrayList<>();
        FeatureModel model = new FeatureModel();
        for (int i = 0; i <12; i++) {
            model.setImg("222");
            model.setTime("僅剩5天13小時30分42秒");
            modelList.add(model);
        }
    }

    /**
     * 初始化Adapter
     */
    private void initSnaAdapter() {
        snapAdapter = new SnapAdapter(App.getContext(),modelList);
        rvCenter.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        //設定滑動時居中對齊
        SnapHelper snapHelper = new LinearSnapHelper();
        snapHelper.attachToRecyclerView(rvCenter);
        rvCenter.setAdapter(snapAdapter);

        //設定滑動時在開始
        snapAdapter = new SnapAdapter(App.getContext(),modelList);
        rvStart.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        SnapHelper snapHelperStart = new GravitySnapHelper(Gravity.START);
        snapHelperStart.attachToRecyclerView(rvStart);
        rvStart.setAdapter(snapAdapter);

        //設定滑動時在末尾
        snapAdapter = new SnapAdapter(App.getContext(),modelList);
        rvTop.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL, false));
        SnapHelper snapHelperTop = new GravitySnapHelper(Gravity.END);
        snapHelperTop.attachToRecyclerView(rvTop);
        rvTop.setAdapter(snapAdapter);
    }

}
介面佈局程式碼:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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.v7.widget.RecyclerView
        android:id="@+id/rv_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"/>
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

實體類程式碼:

/**
 * 作者: njb
 * 時間: 2018/10/12 0012-下午 3:21
 * 描述: 精選
 * 來源:
 */
public class FeatureModel {
    private String title;
    private String name;
    private String img;
    private String time;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getName() {
        return name;
    }

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

    public String getImg() {
        return img;
    }

    public void setImg(String img) {
        this.img = img;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

}

SnapAdapter的程式碼:
/**
 * 作者: njb
 * 時間: 2018/10/19 0019-下午 4:48
 * 描述: 圖片滑動Adapter
 * 來源:
 */
public class SnapAdapter extends RecyclerView.Adapter<SnapAdapter.ViewHolder> {
    private List<FeatureModel> mList;
    Context context;

    public SnapAdapter(Context context, List<FeatureModel> mList) {
        this.context = context;
        this.mList = mList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_special_offer, parent, false);
        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        FeatureModel model = mList.get(position);
        holder.timeTv.setText(model.getTime());
    }

    public long getItemId(int position) {
        return position;
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder{
        private TextView timeTv;
        private ImageView imageView;

        public ViewHolder(View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.iv_shop_img);
            timeTv = itemView.findViewById(R.id.tv_bug_time);
        }
    }
}

item佈局程式碼:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginEnd="15dp">

    <ImageView
        android:id="@+id/iv_shop_img"
        android:layout_width="240dp"
        android:layout_height="150dp"
        android:background="@mipmap/image1"
        android:scaleType="center"
        app:layout_constraintDimensionRatio="w,1:1.63" />

    <TextView
        android:id="@+id/tv_bug_time"
        android:layout_width="172dp"
        android:layout_height="27dp"
        android:background="@drawable/shape_time_13dp"
        android:gravity="center"
        android:text="僅剩5天13小時30分42秒"
        android:textColor="@color/white"
        android:textSize="12sp"
        app:layout_constraintBottom_toBottomOf="@+id/iv_shop_img"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/iv_shop_img" />
</android.support.constraint.ConstraintLayout>

RecyclerView實現效果截圖如下:

小夥伴有興趣可以自己實現一下,有問題歡迎提出,菜鳥寫得不好,還望諒解.

當然,三隻松鼠還有一個圖片放大效果,後面會加上.小夥伴們也可自己新增上