Android仿制淘寶滾動(dòng)圖文條的示例代碼
開(kāi)篇廢話(huà)
產(chǎn)品讓我們將“我的”頁(yè)面改版,上面加了一個(gè)廣告條,非常類(lèi)似淘寶“我的”頁(yè)面的廣告條,然后就自己寫(xiě)了一個(gè),方法比較一般,如果大家有更好的辦法請(qǐng)留言給我,謝謝。 滾動(dòng)圖文條之GitHub地址 ,幫我點(diǎn)個(gè)Star。
滾動(dòng)圖文條
大概效果就是下圖這樣。
滾動(dòng)圖文條
思路
- 寫(xiě)一個(gè)不可用手滑動(dòng)的RecyclerView
- 使用Handler定時(shí)RecyclerView自動(dòng)滑動(dòng)到下一個(gè)Item
- 使用smoothScrollToPosition使其平滑地滑動(dòng)
開(kāi)始工作
做一些基本工作
寫(xiě)一個(gè)AdModel類(lèi)。
public class AdModel { public String title; public String content; public AdModel(String title, String content) { this.title = title; this.content = content; } }
寫(xiě)一些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>
寫(xiě)AdAdapter類(lèi)。
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中寫(xiě)如下代碼。
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)圖文條
寫(xiě)在后面
這個(gè)Demo比較簡(jiǎn)單,沒(méi)什么技術(shù)難點(diǎn),如果還是有些不懂的,可以留言,我在文中可以做更多的解釋。如果有大佬有更好的解決方案,望指教。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android開(kāi)發(fā)中的9個(gè)常見(jiàn)錯(cuò)誤和解決方法
這篇文章主要介紹了Android開(kāi)發(fā)中的9個(gè)常見(jiàn)錯(cuò)誤和解決方法,這是Android開(kāi)發(fā)中最常見(jiàn)的9個(gè)錯(cuò)誤,經(jīng)過(guò)各種各樣的整理,以及和熱心網(wǎng)友討論總結(jié)而來(lái),需要的朋友可以參考下2015-01-01Android?Flutter實(shí)現(xiàn)創(chuàng)意時(shí)鐘的示例代碼
時(shí)鐘這個(gè)東西很奇妙,總能當(dāng)做創(chuàng)意實(shí)現(xiàn)的入口。這篇文章主要介紹了如何通過(guò)Android?Flutter實(shí)現(xiàn)一個(gè)創(chuàng)意時(shí)鐘,感興趣的小伙伴可以了解一下2023-03-03Android基礎(chǔ)知識(shí)之frame動(dòng)畫(huà)效果
Android基礎(chǔ)知識(shí)之tween動(dòng)畫(huà)效果,Android一共提供了兩種動(dòng)畫(huà),這篇文章主要介紹了Android動(dòng)畫(huà)效果之frame動(dòng)畫(huà),感興趣的小伙伴們可以參考一下2016-06-06解決Android啟動(dòng)APP的一瞬間系統(tǒng)欄會(huì)變成藍(lán)色問(wèn)題
這篇文章主要介紹了解決Android啟動(dòng)APP的一瞬間系統(tǒng)欄會(huì)變成藍(lán)色問(wèn)題,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-06-06Android判斷用戶(hù)2G/3G/4G移動(dòng)數(shù)據(jù)網(wǎng)絡(luò)
這篇文章主要介紹了Android判斷用戶(hù)2G/3G/4G移動(dòng)數(shù)據(jù)網(wǎng)絡(luò)的方法,感興趣的小伙伴們可以參考一下2015-12-12如何在android中制作一個(gè)方向輪盤(pán)詳解
這篇文章主要給大家介紹了關(guān)于如何在android中制作一個(gè)方向輪盤(pán)的相關(guān)資料,這個(gè)是在手游領(lǐng)域中很常見(jiàn)的用于控制方向的輪盤(pán),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09詳解Android中的ActivityThread和APP啟動(dòng)過(guò)程
ActivityThread就是我們常說(shuō)的主線(xiàn)程或UI線(xiàn)程,ActivityThread的main方法是整個(gè)APP的入口,本篇深入學(xué)習(xí)下ActivityThread,順便了解下APP和Activity的啟動(dòng)過(guò)程。2021-06-06