Android recycleview(kotlin)实现上下滚动,类似中奖信息跑马灯
程序员文章站
2022-03-13 20:54:11
...
数据展示我们一般都是通过recycleview来处理,下面记录一下滚动需求的实现方法和步骤:
先看看效果:
第一步:
新建一个实体类(Wininfo ):
class Wininfo {
var title: String? = null
var test: String? = null
}
第二:新建revy的适配器(MyAdapterItem_auto):
/**
* 适配器
*/
public class MyAdapterItem_auto extends RecyclerView.Adapter<MyAdapterItem_auto.ViewHolder> {
List<Wininfo> list;
Context context;
private boolean bool;
public MyAdapterItem_auto(List<Wininfo> list, Context context) {
this.list = list;
this.context = context;
}
//创建新View,被LayoutManager所调用
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_recywin, viewGroup, false);
ViewHolder vh = new ViewHolder(view);
return vh;
}
//将数据与界面进行绑定的操作
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
Wininfo wininfo = list.get(position);
viewHolder.tv_title.setText(wininfo.getTitle() + ":\n");
viewHolder.tv_test.setText(wininfo.getTest());
}
//获取数据的数量
@Override
public int getItemCount() {
return list == null ? 0 : list.size();
}
//自定义的ViewHolder,持有每个Item的的所有界面元素
class ViewHolder extends RecyclerView.ViewHolder {
TextView tv_title, tv_test;
ViewHolder(View view) {
super(view);
tv_title = view.findViewById(R.id.tv_title);
tv_test = view.findViewById(R.id.tv_test);
}
}
}
适配器里面的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4"
android:gravity="center"
android:textSize="50sp"
android:text="烧鸭饭"/>
<TextView
android:id="@+id/tv_test"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="50sp"
android:text="恭喜手机尾号123xxxxxxxx中奖啦"/>
</LinearLayout>
第三;重新自定义recycleview(AutoPollRecyclerView):
package com.example.test_01.recy;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import java.lang.ref.WeakReference;
public class AutoPollRecyclerView extends RecyclerView {
private static final long TIME_AUTO_POLL =1;
AutoPollTask autoPollTask;
private boolean running; //标示是否正在自动轮询
private boolean canRun;//标示是否可以自动轮询,可在不需要的是否置false
public AutoPollRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
autoPollTask = new AutoPollTask(this);
}
static class AutoPollTask implements Runnable {
private final WeakReference<AutoPollRecyclerView> mReference;
//使用弱引用持有外部类引用->防止内存泄漏
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.scrollBy(2, 2);
recyclerView.postDelayed(recyclerView.autoPollTask, recyclerView.TIME_AUTO_POLL);
}
}
}
//开启:如果正在运行,先停止->再开启
public void start() {
if (running)
stop();
canRun = true;
running = true;
postDelayed(autoPollTask, TIME_AUTO_POLL);
}
public void stop() {
running = false;
removeCallbacks(autoPollTask);
}
@Override
public boolean onTouchEvent(MotionEvent e) {
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
if (running)
stop();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_OUTSIDE:
if (canRun)
start();
break;
}
//return false,注释掉onTouchEvent()方法里面的stop和start方法,则列表自动滚动且不可触摸
return super.onTouchEvent(e);}
}
第四步 无缝数据底部回到顶部(RecyclerViewScrollHelper ):
public class RecyclerViewScrollHelper {
public static void scrollToPosition(RecyclerView recyclerView, int position){
RecyclerView.LayoutManager manager1 = recyclerView.getLayoutManager();
if (manager1 instanceof LinearLayoutManager) {
LinearLayoutManager manager = (LinearLayoutManager) manager1;
final TopSmoothScroller mScroller = new TopSmoothScroller(recyclerView.getContext());
mScroller.setTargetPosition(position);
manager.startSmoothScroll(mScroller);
}
}
public static class TopSmoothScroller extends LinearSmoothScroller {
TopSmoothScroller(Context context) {
super(context);
}
@Override
protected int getHorizontalSnapPreference() {
return SNAP_TO_START;
}
@Override
protected int getVerticalSnapPreference() {
return SNAP_TO_START;
}
}
}
第五步 新建测试的activity的布局(activity_recy):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:gravity="center"
tools:context=".recy.RecyActivity">
<com.example.test_01.recy.AutoPollRecyclerView
android:id="@+id/recy01"
android:layout_width="match_parent"
android:layout_height="300dp"/>
</RelativeLayout>
第六步 activity测试:
package com.example.test_01.recy
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.test_01.R
import kotlinx.android.synthetic.main.activity_recy.*
import java.util.*
class RecyActivity : AppCompatActivity() {
//滚动版
var myAdapterItem_doctor_auto: MyAdapterItem_auto? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_recy)
var list: MutableList<Wininfo>? = ArrayList()
for (s in 0..9) {
var tt = Wininfo()
tt.test = "恭喜手机尾号18xxxxxx3541中奖"
tt.title = "奶茶店$s"
list!!.add(tt)
}
//垂直方向
val linearLayoutManager = LinearLayoutManager(this)
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL)
recy01.setLayoutManager(linearLayoutManager)
myAdapterItem_doctor_auto = MyAdapterItem_auto(list, this) //滚动版
recy01.setAdapter(myAdapterItem_doctor_auto)
recy01.start()
recy01.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (isSlideToBottom(recyclerView)) {
// LogUtils.e("是否滑动到底部?" + isSlideToBottom(recyclerView) + "");
runOnUiThread(Runnable { // recy_doctor_all.scrollToPosition(0);
RecyclerViewScrollHelper.scrollToPosition(recy01, 0)
})
}
}
})
}
private fun isSlideToBottom(recyclerView: RecyclerView?): Boolean {
if (recyclerView == null) return false
return if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset() >= recyclerView.computeVerticalScrollRange()) true else false
}
}
到这里就实现了滚动,虽然这不是最好的办法,我想要的是效果不用从底部跳到0项数据开始滚动,而是从最后一项直接拼接到首项0开始继续循环下去,如果你有更好的方式,评论留言交流一下,实现的方式。
上一篇: UI调试黑科技
下一篇: Android - JetPack