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实现效果截图如下:
小伙伴有兴趣可以自己实现一下,有问题欢迎提出,菜鸟写得不好,还望谅解.
当然,三只松鼠还有一个图片放大效果,后面会加上.小伙伴们也可自己添加上
项目地址:https://gitee.com/jackning_admin/Glidedemo