public class MarqueeRecyclerView extends RecyclerView {
Thread thread = null;
AtomicBoolean shouldContinue = new AtomicBoolean(false);
Handler mHandler;
public MarqueeRecyclerView(@NonNull Context context) {
super(context);
}
public MarqueeRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MarqueeRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
private void init() {
//主线程的handler,用于执行Marquee的滚动消息
mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 1://不论是竖直滚动还是水平滚动,都是偏移5个像素
MarqueeRecyclerView.this.scrollBy(5, 5);
break;
}
}
};
if (thread == null) {
thread = new Thread() {
@Override
public void run() {
while (shouldContinue.get()) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg=mHandler.obtainMessage();
msg.what=1;
msg.sendToTarget();
}
//退出循环时清理handler
mHandler=null;
}
};
}
}
@Override
/**
* 在附到窗口的时候开始滚动
*/
protected void onAttachedToWindow() {
super.onAttachedToWindow();
shouldContinue.set(true);
init();
thread.start();
}
@Override
/**
* 在脱离窗口时处理相关内容
*/
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
stopMarquee();
}
/**
* 停止滚动
*/
public void stopMarquee() {
shouldContinue.set(false);
thread = null;
}
}
public class MarqueeRecyclerAdapter extends RecyclerView.Adapter<MarqueeRecyclerAdapter.MarqueHolder> {
private List<String> mData;
private int size;
private LayoutInflater mLayoutInflater;
public MarqueeRecyclerAdapter(List<String> data, Context context) {
mData = data;
size=mData.size();
mLayoutInflater= LayoutInflater.from(context);
}
@NonNull
@Override
public MarqueHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view=mLayoutInflater.inflate(R.layout.marque_item,null,false);
return new MarqueHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MarqueHolder marqueHolder, int position) {
marqueHolder.tv.setText(mData.get(position%size));
}
@Override
public int getItemCount() {
return Integer.MAX_VALUE;
}
class MarqueHolder extends RecyclerView.ViewHolder {
TextView tv;
public MarqueHolder(View view) {
super(view);
tv = view.findViewById(R.id.tv);
}
}
}
public class MainActivity extends AppCompatActivity {
private List<String> data;
private MarqueeRecyclerAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MarqueeRecyclerView marqueeView =findViewById(R.id.marqueView);
LinearLayoutManager lm=new LinearLayoutManager(this);
lm.setOrientation(LinearLayoutManager.VERTICAL);//设置是横还是竖
marqueeView.setLayoutManager(lm);
adapter = new MarqueeRecyclerAdapter(getData(),this);
marqueeView.setAdapter(adapter);
}
private List<String> getData(){
data = new ArrayList<>();
for(int i = 0;i<10;i++){
data.add("第"+i+"条");
}
return data;
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
>
<com.gaidian.text.MarqueeRecyclerView
android:id="@+id/marqueView"
android:layout_width="match_parent"
android:layout_height="200dp"
/>
</RelativeLayout>
<?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="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="30sp"
android:id="@+id/tv"/>
</LinearLayout>