当前位置:网站首页>(original) customize a scrolling recyclerview
(original) customize a scrolling recyclerview
2022-07-25 14:40:00 【Android_ xiong_ st】
Effect display
RecyclerView You can customize it into various styles you want
For example, the home page Banner, Card style, etc
Today, let's share a rolling RecyclerView, Let's see the effect first :
Here is how to realize
Adapter
First of all adapter, Because to achieve infinite scrolling , So in getItemCount Method returns Integer.MAX_VALUE
The specific code is as follows :
public class AutoPollAdapter extends RecyclerView.Adapter {
/** * Event callback monitoring */
private OnItemClickListener onItemClickListener;
private Context context;
private List<AutoBean> listBeans;
public AutoPollAdapter(Context context, List<AutoBean> listBeans) {
this.context = context;
this.listBeans = listBeans;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Instantiate the view
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_auto_poll, parent, false);
// Instantiation viewholder
ViewHolder viewHolder = new ViewHolder(view);
viewHolder.imgHead = view.findViewById(R.id.img_head);
viewHolder.tvName = view.findViewById(R.id.tv_name);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ViewHolder holder1 = (ViewHolder) holder;
holder1.tvName.setText(listBeans.get(position % listBeans.size()).tvname);
Glide.with(context).load(listBeans.get(position % listBeans.size()).url).into(holder1.imgHead);
holder1.tvName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onItemClickListener.onItemClick((position % listBeans.size()));
}
});
}
@Override
public int getItemCount() {
// Mainly here , Achieve the effect of wireless rotation
return Integer.MAX_VALUE;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView tvName;
ImageView imgHead;
public ViewHolder(View itemView) {
super(itemView);
}
}
/** * Set callback monitor * * @param listener */
public void setOnItemClickListener(OnItemClickListener listener) {
this.onItemClickListener = listener;
}
public interface OnItemClickListener {
void onItemClick(int position);
}
}
dependent xml also bean Also put on :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:orientation="horizontal" android:gravity="center_vertical" android:layout_height="60dp">
<ImageView android:id="@+id/img_head" android:layout_width="56dp" android:layout_height="56dp" android:src="@drawable/ic_launcher" />
<TextView android:id="@+id/tv_name" android:text=" test " android:layout_marginLeft="10dp" android:layout_width="match_parent" android:layout_height="wrap_content" />
</LinearLayout>
public class AutoBean {
String tvname;
String url;
public AutoBean(String tvname, String url) {
this.tvname = tvname;
this.url = url;
}
}
Self defined LinearLayoutManager
Customize a layoutManager, To control the sliding speed :
public class ScrollSpeedLinearLayoutManger extends LinearLayoutManager {
private float MILLISECONDS_PER_INCH = 0.03f;
private Context contxt;
public ScrollSpeedLinearLayoutManger(Context context) {
super(context);
this.contxt = context;
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
LinearSmoothScroller linearSmoothScroller =
new LinearSmoothScroller(recyclerView.getContext()) {
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return ScrollSpeedLinearLayoutManger.this
.computeScrollVectorForPosition(targetPosition);
}
@Override
protected float calculateSpeedPerPixel
(DisplayMetrics displayMetrics) {
setSpeedSlow();
return MILLISECONDS_PER_INCH / displayMetrics.density;
// return 7;
// Slide back one pixel How many milliseconds does it take
}
};
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}
public void setSpeedSlow() {
// Use it here by yourself density Go by , I hope the sliding speed is the same on devices with different resolutions
//0.3f It is a value estimated by oneself , It can be modified according to different needs
MILLISECONDS_PER_INCH = contxt.getResources().getDisplayMetrics().density * 3f;
}
public void setSpeedFast() {
MILLISECONDS_PER_INCH = contxt.getResources().getDisplayMetrics().density * 0.03f;
}
}
Self defined RecyclerView
And then put your own RecyclerView:
public class AutoPollRecyclerView extends RecyclerView {
private static final long TIME_AUTO_POLL_1 = 2000;
AutoPollTask autoPollTask;
private int index = 2;// This value is very important , Slide the animation to the first few
private boolean running; // Indicates whether automatic polling is in progress
private boolean canRun;// Indicates whether automatic polling is possible , It can be set when it is not needed false
public AutoPollRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
autoPollTask = new AutoPollTask(this);
}
/*** * You can only slide one at a time item( Shuffling figure ) */
static class AutoPollTask implements Runnable {
private final WeakReference<AutoPollRecyclerView> mReference;
// Use weak references to hold external class references -> Prevent memory leaks
public AutoPollTask(AutoPollRecyclerView reference) {
this.mReference = new WeakReference<AutoPollRecyclerView>(reference);
}
@Override
public void run() {
AutoPollRecyclerView recyclerView = mReference.get();
if (recyclerView != null && recyclerView.running && recyclerView.canRun) {
recyclerView.smoothScrollToPosition(++recyclerView.index);
recyclerView.postDelayed(recyclerView.autoPollTask, TIME_AUTO_POLL_1);
}
}
}
// Turn on : If it's running , First stop -> And open
public void start() {
if (running)
stop();
canRun = true;
running = true;
postDelayed(autoPollTask, TIME_AUTO_POLL_1);
}
public void stop() {
running = false;
removeCallbacks(autoPollTask);
}
// Achieve a gradient effect
Paint mPaint;
private int layerId;
private LinearGradient linearGradient;
/** * No sliding * @param e * @return */
public boolean onTouchEvent(MotionEvent e) {
return true;
}
/** * No sliding * @param e * @return */
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
return false;
}
private int preWidth = 0;// Recyclerview When the width changes dynamically , Monitor the width of each time
public void doTopGradualEffect(final int itemViewWidth) {
mPaint = new Paint();
// dst_in Pattern , Realize that the bottom transparency is displayed synchronously with the top transparency ( That is, when the upper layer is transparent , The lower layer is transparent , It's not that the upper layer covers the lower layer )
final Xfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
mPaint.setXfermode(xfermode);
addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void onDrawOver(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(canvas, parent, state);
// When linearGradient If it is empty, it means that it is drawn for the first time or Recyclerview When the width changes , Recalculate the transparent position
if (linearGradient == null || preWidth != parent.getWidth()) {
// Transparent position from the last itemView Half way to Recyclerview On the far right of
linearGradient = new LinearGradient(parent.getWidth() - (itemViewWidth / 2), 0.0f, parent.getWidth(), 0.0f, new int[]{
Color.BLACK, 0}, null, Shader.TileMode.CLAMP);
preWidth = parent.getWidth();
}
mPaint.setXfermode(xfermode);
mPaint.setShader(linearGradient);
canvas.drawRect(0.0f, 0.0f, parent.getRight(), parent.getBottom(), mPaint);
mPaint.setXfermode(null);
canvas.restoreToCount(layerId);
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
// here Paint Parameters of are passed here null, In the incoming mPaint There will be the problem of flashing black screen for the first time
// Be careful saveLayer Cannot save nor move to onDrawOver In the method
layerId = c.saveLayer(0.0f, 0.0f, (float) parent.getWidth(), (float) parent.getHeight(), null, Canvas.ALL_SAVE_FLAG);
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
}
});
}
}
One thing to note here , Because our scrolling , I don't want him to slide through his fingers
That is to say, disable RecyclerView Your fingers slide
The general solution is to rewrite layoutManager Two approaches :
canScrollVertically and canScrollHorizontally
return false, Disable left and right sliding and up and down sliding respectively
But this will bring a new problem :
RecyclerVIew Use this method to prevent sliding , adopt smoothScrollToPosition Slide to specified item Our methods have also failed
In this way, the automatic scrolling effect is gone
I didn't use this method , It uses rewriting RecyclerView The next two methods of :
/** * No sliding * @param e * @return */
public boolean onTouchEvent(MotionEvent e) {
return true;
}
/** * No sliding * @param e * @return */
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
return false;
}
So if you want to open the finger slide , Comment on these two methods , Then record the position where the monitor slides , Reset auto slide ( That's important )
You can realize this by yourself
Use
Last , Paste the code used :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.mydemo.recy.AutoPollRecyclerView
android:id="@+id/recycleView"
android:fadingEdge="vertical"
android:scrollbars="none"
android:fadingEdgeLength="10dp"
android:layout_width="match_parent"
tools:listitem="@layout/item_auto_poll"
android:layout_height="180dp"/>
</FrameLayout>
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_recy);
ScrollSpeedLinearLayoutManger layoutManager = new ScrollSpeedLinearLayoutManger(this);
layoutManager.setSmoothScrollbarEnabled(true);
layoutManager.setAutoMeasureEnabled(true);
AutoPollRecyclerView recyclerView = findViewById(R.id.recycleView);
recyclerView.setLayoutManager(layoutManager);// Layout manager .
recyclerView.setHasFixedSize(true);// If Item Simple enough , The height is certain , open FixSize Will improve performance .
recyclerView.setItemAnimator(new DefaultItemAnimator());// Set up Item Default animation , Plus is OK , It's ok if you don't add it .
ArrayList<AutoBean> list = new ArrayList<>();
list.add(new AutoBean(" Doraemon A dream ","https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2Fedpic_source%2F91%2F81%2Fd7%2F9181d7d8787f7e96f0017da5e61ad27d.jpg&refer=http%3A%2F%2Fup.enterdesk.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1659497299&t=05f317ff452b3f1a452f7e06c9ce8703"));
list.add(new AutoBean(" puppy ","https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F201610%2F17%2F20161017213843_EeViB.thumb.1000_0.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1659497393&t=6f8f90c5b409231ef5902aafc7464d31"));
list.add(new AutoBean(" Cartoon head ","https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202107%2F09%2F20210709142454_dc8dc.thumb.1000_0.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1659497417&t=1a38f19555bcb59f5f9e127126fba84a"));
list.add(new AutoBean(" Fire shadow avatar ","https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13207652291%2F1000.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1659497813&t=a911ff64c37a57aeb95a6f31d13a573b"));
AutoPollAdapter autoPollAdapter = new AutoPollAdapter(MainActivity.this, list);
autoPollAdapter.setOnItemClickListener(new AutoPollAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
Log.d("AutoPollAdapter", " Click. " + (position));
Toast.makeText(MainActivity.this, " Click. " + (position ), Toast.LENGTH_SHORT).show();
}
});
recyclerView.setAdapter(autoPollAdapter);
recyclerView.start();
DisplayMetrics dm = getResources().getDisplayMetrics();
recyclerView.doTopGradualEffect(dm.widthPixels);
}
}
Last but not least :
If you want to recycleview It shows item The quantity is an integer
For example, three ,
that recycleview Height , Be sure to set it to item An integral multiple of the height of
For example, three times , It means you can display three item, Five times shows five .
边栏推荐
- Doris learning notes integration with other systems
- filters获取data中的数据;filters使用data中的数据
- Live classroom system 05 background management system
- awk从入门到入土(20)awk解析命令行参数
- 关于RDBMS和非RDBMS【数据库系统】
- How to make a set of code fit all kinds of screens perfectly?
- The concept and operation rules of calculus of variations
- 二维数组赋初值你会几种方法?
- spark参数调整调优
- Is it safe for Guolian securities to buy shares and open an account?
猜你喜欢

Melodic + Realsense D435i 配置及错误问题解决

云安全技术发展综述

easygui使用的语法总结

SQL优化的一些建议,希望可以帮到和我一样被SQL折磨的你

如何让一套代码完美适配各种屏幕?

51单片机学习笔记(2)

Deng Qinglin, a technical expert of Alibaba cloud: Best Practices for disaster recovery and remote multi activity across availability zones on cloud

Gameframework making games (II) making UI interface

51 single chip microcomputer learning notes (2)

The main function of component procurement system, digital procurement helps component enterprises develop rapidly
随机推荐
51 single chip microcomputer learning notes (2)
sqli-labs Basic Challenges Less11-22
Gameframework making games (I)
LeetCode-198-打家劫舍
元器件采购系统的主要功能,数字化采购助力元器件企业飞速发展
Awk from getting started to digging in (21) awk script debugging
苹果官网产品打折 买iPhone 13 Pro Max 可省600元
filters获取data中的数据;filters使用data中的数据
Software testing -- 1. Outline of software testing knowledge
二维数组赋初值你会几种方法?
PHP website design ideas
SSM framework integration, simple case
The solution to the problem that the progress bar of ros2 installation connext RMW is stuck at 13%
Runtimeerror: CUDA out of memory (solved) [easy to understand]
Initial flask and simple application
Practical guide for network security emergency response technology (Qianxin)
网络安全应急响应技术实战指南(奇安信)
The concept and operation rules of calculus of variations
物理量与单位符号的书写标准
Awk from getting started to digging in (20) awk parsing command line parameters