Android仿制淘寶滾動(dòng)圖文條的示例代碼
開(kāi)篇廢話
產(chǎn)品讓我們將“我的”頁(yè)面改版,上面加了一個(gè)廣告條,非常類似淘寶“我的”頁(yè)面的廣告條,然后就自己寫了一個(gè),方法比較一般,如果大家有更好的辦法請(qǐng)留言給我,謝謝。 滾動(dòng)圖文條之GitHub地址 ,幫我點(diǎn)個(gè)Star。
滾動(dòng)圖文條
大概效果就是下圖這樣。

滾動(dòng)圖文條
思路
- 寫一個(gè)不可用手滑動(dòng)的RecyclerView
- 使用Handler定時(shí)RecyclerView自動(dòng)滑動(dòng)到下一個(gè)Item
- 使用smoothScrollToPosition使其平滑地滑動(dòng)
開(kāi)始工作
做一些基本工作
寫一個(gè)AdModel類。
public class AdModel {
public String title;
public String content;
public AdModel(String title, String content) {
this.title = title;
this.content = content;
}
}
寫一些item_ad布局。
<?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:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:minHeight="50dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:background="@null"
tools:background="@color/black">
<LinearLayout
android:id="@+id/ll_ad"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title"
tools:text="會(huì)員身份0元搶"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:textColor="@color/white"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_content"
tools:text="送你體驗(yàn)會(huì)員"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:textColor="@color/white"
android:textSize="10sp" />
</LinearLayout>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<ImageView
android:id="@+id/iv_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="15dp"
android:src="@drawable/icon"/>
</LinearLayout>
寫AdAdapter類。
public class AdAdapter extends RecyclerView.Adapter<AdAdapter.ViewHolder> {
private Context mContext;
private OnItemClickListener onItemClickListener;
private LayoutInflater mInflater;
private List<AdModel> mDataList;
public AdAdapter(Context context, List<AdModel> datas) {
this.mContext = context;
mDataList = datas;
mInflater = LayoutInflater.from(context);
}
@Override
public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.item_ad, null);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(ViewHolder holder, final int p) {
if (mDataList == null || mDataList.size() ==0){
return;
}
if (holder != null) {
final int position = p % mDataList.size();
holder.mTvTitle.setText(mDataList.get(position).title);
holder.mTvContent.setText(mDataList.get(position).content);
holder.mIvIcon.setImageResource(R.drawable.icon);
holder.viewRoot.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onItemClickListener != null) {
onItemClickListener.onItemClick(v, position);
}
}
});
}
}
public void setOnItemClickListener(OnItemClickListener clickListener) {
this.onItemClickListener = clickListener;
}
@Override
public int getItemCount() {
return mDataList == null ? 0 : Integer.MAX_VALUE;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public View viewRoot;
public TextView mTvTitle;
public TextView mTvContent;
public ImageView mIvIcon;
public ViewHolder(View itemView) {
super(itemView);
viewRoot = itemView.findViewById(R.id.layout);
mTvTitle = itemView.findViewById(R.id.tv_title);
mTvContent = itemView.findViewById(R.id.tv_content);
mIvIcon = itemView.findViewById(R.id.iv_icon);
}
}
/**
* RecyclerView的item點(diǎn)擊監(jiān)聽(tīng)接口
*/
public interface OnItemClickListener {
void onItemClick(View v, int position);
}
}
頁(yè)面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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.cc.scrolladbar.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_ad"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginEnd="20dp"
android:layout_marginStart="20dp"
android:layout_marginTop="60dp"
android:nestedScrollingEnabled="false"
android:background="@color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
重點(diǎn)代碼
在MainActivity中寫如下代碼。
package com.cc.scrolladbar;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.LinearSmoothScroller;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* Created by guoshichao on 2018/8/16
* QQ:1169380200
*/
public class MainActivity extends AppCompatActivity {
private static final int SCROLL_AD = 0;//會(huì)員輪播廣告
public static final int DEFAULT_SCROLL_INTERVAL = 3000;//會(huì)員輪播廣告間隔時(shí)間
public static final int DEFAULT_SCROLL_ANIMATION_TIME = 500;//會(huì)員輪播廣告動(dòng)畫(huà)時(shí)長(zhǎng)
private RecyclerView mRvAd;
private AdAdapter mAdapter;
private List<AdModel> mAdList;
private AdHandler mHandler;
private int nowScrollPosition = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initList();
}
@Override
public void onStart() {
super.onStart();
scrollVipAdOnce(nowScrollPosition);//防止滑動(dòng)一半切到別的頁(yè)面使滑動(dòng)完成
if (mHandler != null) {
sendScrollMessage(DEFAULT_SCROLL_INTERVAL);
}
}
@Override
public void onStop() {
super.onStop();
if (mHandler != null) {
mHandler.removeMessages(SCROLL_AD);
}
}
private void initList() {
mAdList = new ArrayList<>();
mAdList.add(new AdModel("第一條廣告標(biāo)題", "我是第一條廣告的內(nèi)容哦~"));
mAdList.add(new AdModel("第二條廣告標(biāo)題", "我是第二條廣告的內(nèi)容哦~"));
mAdList.add(new AdModel("第三條廣告標(biāo)題", "我是第三條廣告的內(nèi)容哦~"));
LinearLayoutManager manager = new LinearLayoutManager(this) {
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
LinearSmoothScroller smoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
// 為了平滑滑動(dòng)返回:滑過(guò)1px時(shí)經(jīng)歷的時(shí)間(ms)。
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return (float) (DEFAULT_SCROLL_ANIMATION_TIME / displayMetrics.densityDpi);
}
};
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
};
mRvAd = (RecyclerView) findViewById(R.id.rv_ad);
mRvAd.setLayoutManager(manager);
mAdapter = new AdAdapter(this, mAdList);
mRvAd.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new AdAdapter.OnItemClickListener() {
@Override
public void onItemClick(View v, int position) {
//點(diǎn)擊跳轉(zhuǎn)到指定廣告頁(yè)
}
});
mHandler = new AdHandler();
sendScrollMessage(DEFAULT_SCROLL_INTERVAL);
}
private void scrollVipAdOnce(int position) {
if (mAdList != null && mAdList.size() > 1) {
//平滑滑動(dòng)到指定位置
mRvAd.smoothScrollToPosition(position);
}
}
private void sendScrollMessage(long delayMillis) {
mHandler.removeMessages(SCROLL_AD);
mHandler.sendEmptyMessageDelayed(SCROLL_AD, delayMillis);
}
private class AdHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case SCROLL_AD:
nowScrollPosition++;
scrollVipAdOnce(nowScrollPosition);
sendScrollMessage(DEFAULT_SCROLL_INTERVAL);
break;
default:
break;
}
}
}
}
重點(diǎn)分析
其中有一段代碼比較重要。
LinearLayoutManager manager = new LinearLayoutManager(this) {
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
LinearSmoothScroller smoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
// 為了平滑滑動(dòng)返回:滑過(guò)1px時(shí)經(jīng)歷的時(shí)間(ms)。
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return (float) (DEFAULT_SCROLL_ANIMATION_TIME / displayMetrics.densityDpi);
}
};
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
};
這里是為了平滑滑動(dòng)。因?yàn)榫嚯x比較短小或者別的原因,mRvAd.smoothScrollToPosition(position)無(wú)法使其平滑地滑動(dòng)。故加以上代碼。
我的完成圖如下。

滾動(dòng)圖文條
寫在后面
這個(gè)Demo比較簡(jiǎn)單,沒(méi)什么技術(shù)難點(diǎn),如果還是有些不懂的,可以留言,我在文中可以做更多的解釋。如果有大佬有更好的解決方案,望指教。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
android全局監(jiān)控click事件的四種方式(小結(jié))
本篇文章主要介紹了android全局監(jiān)控click事件的四種方式(小結(jié)),詳細(xì)介紹如何在全局上去監(jiān)聽(tīng) click 點(diǎn)擊事件,并做些通用處理或是攔截,有興趣的可以了解一下2017-08-08
Android實(shí)現(xiàn)Activity之間通信的方法
這篇文章主要介紹了Android實(shí)現(xiàn)Activity之間通信的方法,涉及Android中Activity實(shí)現(xiàn)數(shù)據(jù)的發(fā)送及接收相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
利用Android從0到1實(shí)現(xiàn)一個(gè)流布局控件
新項(xiàng)目用到了一種全新布局,Android標(biāo)簽流式布局的功能,正好一直說(shuō)給大家講自己定義控件的實(shí)現(xiàn),這篇文章主要給大家介紹了關(guān)于利用Android從0到1如何實(shí)現(xiàn)一個(gè)流布局控件的相關(guān)資料,需要的朋友可以參考下2021-08-08
AndroidStudio圖片壓縮工具ImgCompressPlugin使用實(shí)例
這篇文章主要為大家介紹了AndroidStudio圖片壓縮工具ImgCompressPlugin使用實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
配置android開(kāi)發(fā)環(huán)境時(shí)出現(xiàn)eclipse獲取不到ADT的解決方法
這篇文章主要介紹了配置android開(kāi)發(fā)環(huán)境時(shí)出現(xiàn)eclipse獲取不到ADT的解決方法,涉及針對(duì)開(kāi)發(fā)環(huán)境hosts文件域名映射的修改及eclipse配置的修改技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-12-12
Android WebView調(diào)用本地相冊(cè)的方法
這篇文章主要為大家詳細(xì)介紹了Android WebView調(diào)用本地相冊(cè)的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12

