赞
踩
需求场景来源于用户长时间未操作屏幕,唤出的屏保界面,屏保界面效果底部为横向滚动商品小图,上方为商品大图 ~
友情提示:关于如何监听用户长时间未操作屏幕的功能实现可 GO → go 此处 ~
这应该是去年做的一个简单功能,最初是直接套用的别人代码,但是使用中发现存在一些bug和不足,同时适用场景有限,所以特在修改、补全后记录于此 ~
Look here ~
此版已具备屏保的基本功能,可直接使用~
功能:
ScreenAdapter
package nk.com.carouseldemo; 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.ImageView; import java.util.List; /** * @author MrLiu * @date 2020/12/10 * desc */ public class ScreenAdapter extends RecyclerView.Adapter<ScreenAdapter.ViewHolder> { private Context context; private List<Integer> mDataList; private OnItemClickListener onItemClickListener; public ScreenAdapter(Context context, List<Integer> dataList) { this.context = context; this.mDataList = dataList; } @Override public int getItemCount() { return Integer.MAX_VALUE; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.item_screen, parent, false); final ViewHolder vh = new ViewHolder(view); return vh; } @Override public void onBindViewHolder(ViewHolder holder, int position) { int newPos = position % mDataList.size(); holder.mDisplay.setImageResource(mDataList.get(newPos)); holder.itemView.setTag(position); } class ViewHolder extends RecyclerView.ViewHolder { ImageView mDisplay; public ViewHolder(View itemView) { super(itemView); mDisplay = itemView.findViewById(R.id.iv_display); } } }
item_screen - 可不同
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#4CA9EE" android:orientation="vertical"> <ImageView android:id="@+id/iv_display" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginTop="5dp" android:layout_marginBottom="5dp" android:padding="5dp" tools:src="@mipmap/ic_launcher" /> </LinearLayout>
MainActivity
package nk.com.carouseldemo; import android.annotation.SuppressLint; import android.os.Handler; import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { ImageView mDisplay; RecyclerView mBottomRv; //此处数据源为项目内的图片,不可套用 private Integer[] mImgIds = {R.mipmap.banner_1, R.mipmap.banner_2, R.mipmap.banner_3}; private List<Integer> imgLists; private ScreenAdapter screenAdapter; private Handler mHandler = new Handler(); private LinearLayoutManager layoutManager; private int oldItem = 0; Runnable scrollRunnable = new Runnable() { @Override public void run() { mBottomRv.scrollBy(1, 0); int firstItem = layoutManager.findFirstVisibleItemPosition(); if (firstItem != oldItem && firstItem > 0) { oldItem = firstItem; mDisplay.setImageResource(imgLists.get(oldItem % imgLists.size())); } mHandler.postDelayed(scrollRunnable, 10); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDisplay = findViewById(R.id.iv_display); mBottomRv = findViewById(R.id.rv_bottom_screen); initData(); } public void initData() { //模拟数据源 imgLists = new ArrayList<>(); for (int i = 0; i < mImgIds.length; i++) { imgLists.add(mImgIds[i]); } //小优化:正常开发中一般为了用户体验初始的时候先手动加载第一个视图 mDisplay.setImageResource(imgLists.get(0)); screenAdapter = new ScreenAdapter(this, imgLists); layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); mBottomRv.setLayoutManager(layoutManager); mBottomRv.setAdapter(screenAdapter); mBottomRv.setOnTouchListener(new View.OnTouchListener() { @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.e("tag", "down"); mHandler.removeCallbacks(scrollRunnable); break; case MotionEvent.ACTION_MOVE: Log.e("tag", "move"); int firstItem = layoutManager.findFirstVisibleItemPosition(); if (firstItem != oldItem && firstItem >= 0) { oldItem = firstItem; mDisplay.setImageResource(imgLists.get(oldItem % imgLists.size())); } break; case MotionEvent.ACTION_UP: Log.e("tag", "up"); mHandler.postDelayed(scrollRunnable, 10); break; } return false; } }); } @Override protected void onResume() { super.onResume(); mHandler.postDelayed(scrollRunnable, 10); } @Override protected void onStop() { super.onStop(); mHandler.removeCallbacks(scrollRunnable); } }
activity_main
<?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"> <ImageView android:id="@+id/iv_display" android:layout_width="match_parent" android:layout_height="0dp" android:scaleType="fitXY" android:src="@mipmap/ic_launcher_round" app:layout_constraintBottom_toTopOf="@+id/rv_bottom_screen" app:layout_constraintTop_toTopOf="parent" /> <android.support.v7.widget.RecyclerView android:id="@+id/rv_bottom_screen" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@+id/iv_display" /> </android.support.constraint.ConstraintLayout>
相比基础版,此版本功能在屏保效果中更常见一些,主要体现在用户触碰屏保页即可执行相关操作
功能:
不支持用户手动滑动底部商品图操作,取而代之的是只要用户触摸屏幕即执行相关操作
功能方面具备基础版中的所有功能,但因onTouch机制问题,在上层事件已经实现了拦截,体现在用户只要触碰屏幕就会执行相关操作,所以针对于RevyclerView的onTouch监听意义不大 ~
实现方面项目版和基础版大部分是相同的,不同点主要在于重写dispatchTouchEvent 事件,记得RecycleView的onTouch内别直接消耗掉事件~
实现过程
MainActivity
package nk.com.carouseldemo; import android.annotation.SuppressLint; import android.os.Handler; import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { ImageView mDisplay; RecyclerView mBottomRv; //此处数据源为项目内的图片,不可套用 private Integer[] mImgIds = {R.mipmap.banner_1, R.mipmap.banner_2, R.mipmap.banner_3}; private List<Integer> imgLists; private ScreenAdapter screenAdapter; private Handler mHandler = new Handler(); private LinearLayoutManager layoutManager; private int oldItem = 0; Runnable scrollRunnable = new Runnable() { @Override public void run() { mBottomRv.scrollBy(1, 0); int firstItem = layoutManager.findFirstVisibleItemPosition(); if (firstItem != oldItem && firstItem > 0) { oldItem = firstItem; mDisplay.setImageResource(imgLists.get(oldItem % imgLists.size())); } mHandler.postDelayed(scrollRunnable, 10); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDisplay = findViewById(R.id.iv_display); mBottomRv = findViewById(R.id.rv_bottom_screen); initData(); } public void initData() { //模拟数据源 imgLists = new ArrayList<>(); for (int i = 0; i < mImgIds.length; i++) { imgLists.add(mImgIds[i]); } //小优化:正常开发中一般为了用户体验初始的时候先手动加载第一个视图 mDisplay.setImageResource(imgLists.get(0)); screenAdapter = new ScreenAdapter(this, imgLists); layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); mBottomRv.setLayoutManager(layoutManager); mBottomRv.setAdapter(screenAdapter); mBottomRv.setOnTouchListener(new View.OnTouchListener() { @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.e("tag", "down"); mHandler.removeCallbacks(scrollRunnable); break; case MotionEvent.ACTION_MOVE: Log.e("tag", "move"); int firstItem = layoutManager.findFirstVisibleItemPosition(); if (firstItem != oldItem && firstItem >= 0) { oldItem = firstItem; mDisplay.setImageResource(imgLists.get(oldItem % imgLists.size())); } break; case MotionEvent.ACTION_UP: Log.e("tag", "up"); mHandler.postDelayed(scrollRunnable, 10); break; } return false; } }); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { // 一般操作习惯是用户点击屏保即跳转首页 ~ 具体看个人需求 // Intent intent = new Intent(this, MainActivity.class); // intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); // startActivity(intent); // onBackPressed(); Log.e("tag", "跳转首页"); return true; } return super.dispatchTouchEvent(ev); } @Override protected void onResume() { super.onResume(); mHandler.postDelayed(scrollRunnable, 10); } @Override protected void onStop() { super.onStop(); mHandler.removeCallbacks(scrollRunnable); } }
基本兼容基础版与业务版,唯一不同在于将业务版中触摸屏幕就关闭屏保的功能移植到了大图的事件上(大图的事件自己写咯 ~),这样就可以适用更多的场景咯 ~
功能:
ScreenAdapter
package nk.com.carouseldemo; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import java.util.List; /** * @author MrLiu * @date 2020/12/10 * desc */ public class ScreenAdapter extends RecyclerView.Adapter<ScreenAdapter.ViewHolder> { private Context context; private List<Integer> mDataList; private OnItemClickListener onItemClickListener; public ScreenAdapter(Context context, List<Integer> dataList) { this.context = context; this.mDataList = dataList; } @Override public int getItemCount() { return Integer.MAX_VALUE; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { final View view = LayoutInflater.from(context).inflate(R.layout.item_screen, parent, false); final ViewHolder vh = new ViewHolder(view); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onItemClickListener.onItemClick(vh.getPosition()); } }); return vh; } @Override public void onBindViewHolder(ViewHolder holder, int position) { int newPos = position % mDataList.size(); holder.mDisplay.setImageResource(mDataList.get(newPos)); holder.itemView.setTag(position); } class ViewHolder extends RecyclerView.ViewHolder { ImageView mDisplay; public ViewHolder(View itemView) { super(itemView); mDisplay = itemView.findViewById(R.id.iv_display); } } public void setOnItemClickListener(OnItemClickListener listener) { this.onItemClickListener = listener; } interface OnItemClickListener { void onItemClick(int position); } }
MainActivity
package nk.com.carouseldemo; import android.annotation.SuppressLint; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { ImageView mDisplay; RecyclerView mBottomRv; private Integer[] mImgIds = {R.mipmap.banner_1, R.mipmap.banner_2, R.mipmap.banner_3}; private List<Integer> imgLists; private ScreenAdapter screenAdapter; private Handler mHandler = new Handler(); private LinearLayoutManager layoutManager; private int oldItem = 0; Runnable scrollRunnable = new Runnable() { @Override public void run() { mBottomRv.scrollBy(1, 0); int firstItem = layoutManager.findFirstVisibleItemPosition(); if (firstItem != oldItem && firstItem > 0) { oldItem = firstItem; mDisplay.setImageResource(imgLists.get(oldItem % imgLists.size())); } mHandler.postDelayed(scrollRunnable, 10); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDisplay = findViewById(R.id.iv_display); mBottomRv = findViewById(R.id.rv_bottom_screen); initData(); screenAdapter.setOnItemClickListener(new ScreenAdapter.OnItemClickListener() { @Override public void onItemClick(int position) { Log.e("tag", "position=" + position); //因为使用的是MAX_VALUE,所以要获得真实position要记得 取% ~ Log.e("tag", "position=" + position % imgLists.size()); } }); } public void initData() { //模拟数据源 imgLists = new ArrayList<>(); for (int i = 0; i < mImgIds.length; i++) { imgLists.add(mImgIds[i]); } //小优化:正常开发中一般为了用户体验初始的时候先手动加载第一个视图 mDisplay.setImageResource(imgLists.get(0)); screenAdapter = new ScreenAdapter(this, imgLists); layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); mBottomRv.setLayoutManager(layoutManager); mBottomRv.setAdapter(screenAdapter); mBottomRv.setOnTouchListener(new View.OnTouchListener() { @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.e("tag", "down"); break; case MotionEvent.ACTION_MOVE: Log.e("tag", "move"); mHandler.removeCallbacks(scrollRunnable); int firstItem = layoutManager.findFirstVisibleItemPosition(); if (firstItem != oldItem && firstItem >= 0) { oldItem = firstItem; mDisplay.setImageResource(imgLists.get(oldItem % imgLists.size())); } break; case MotionEvent.ACTION_UP: Log.e("tag", "up"); mHandler.postDelayed(scrollRunnable, 10); break; } return false; } }); } @Override protected void onResume() { super.onResume(); mHandler.postDelayed(scrollRunnable, 10); } @Override protected void onStop() { super.onStop(); mHandler.removeCallbacks(scrollRunnable); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。