Android 實現無限滾動的ScrollView
阿新 • • 發佈:2019-02-12
用ScrollView實現類似 新聞頭條或廣告圖的無限滾動
效果:
思路是在看智慧社的JavaScript相關視訊時候想到的,具體就是講動畫那個節,實現圖片的無縫滾動
在這裡就不講了(主要是講也講不明白==)
本來是直接寫在Activity裡面,後面為了複用,直接封裝成一個EndlessScrollView類和EndlessHorizontalScrollView類
其中EndlessScrollView類向外暴露一個setData方法,用於設定相應的文字資料。
而EndlessHorizontalScrollView類則暴露了setTextData()和setImageData()兩個方法,用於設定文字和圖片資料
上原始碼:
EndlessScrollView.java
package com.example.jp04.myapplication.views; import android.content.Context; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; import android.widget.LinearLayout; importandroid.widget.ScrollView; import android.widget.TextView; import com.example.jp04.myapplication.R; import com.example.jp04.myapplication.utils.Utils; import java.util.List; /** * 無限滾動的ScrollView(無縫滾動) * Created by jp04 on 2017/3/10. */ public class EndlessScrollView extends ScrollView { private LinearLayout llData; private static final int MESSAGE_SCROLL = 10010; private static int offset = 1000; //滾動的時間間隔 private int pageSize, itemHeight, maxScrollHeight; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE_SCROLL: int scrollY = getScrollY(); int delay = 0; if (scrollY >= maxScrollHeight) { scrollTo(0, 0); } else { smoothScrollBy(0, itemHeight); delay = offset; } postDelayed(new Runnable() { @Override public void run() { sendEmptyMessage(MESSAGE_SCROLL); } }, delay); break; } } }; public EndlessScrollView(Context context) { this(context, null); } public EndlessScrollView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public EndlessScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { llData = new LinearLayout(getContext()); llData.setOrientation(LinearLayout.VERTICAL); llData.setLayoutParams(new ScrollView.LayoutParams(-1, -1)); addView(llData); } public void setData(final List<String> data, final int pageSize) { post(new Runnable() { @Override public void run() { int containerHeight = getMeasuredHeight(); EndlessScrollView.this.pageSize = pageSize; EndlessScrollView.this.itemHeight = containerHeight / pageSize; EndlessScrollView.this.maxScrollHeight = data.size() * itemHeight; data.addAll(data); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(-1, itemHeight); for (int i = 0; i < data.size(); i++) { TextView textView = new TextView(getContext()); textView.setTextColor(Utils.getColor(R.color.textcolor_normal)); textView.setGravity(Gravity.CENTER_VERTICAL); textView.setText(data.get(i)); textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); llData.addView(textView, params); } handler.postDelayed(new Runnable() { @Override public void run() { handler.sendEmptyMessage(MESSAGE_SCROLL); } }, offset); } }); } }
EndlessHorizontalScrollView.java
package com.example.jp04.myapplication.views; import android.content.Context; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; import android.widget.HorizontalScrollView; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.example.jp04.myapplication.R; import com.example.jp04.myapplication.utils.Utils; import com.nostra13.universalimageloader.core.ImageLoader; import java.util.List; /** * 無限滾動的ScrollView(橫向) * Created by jp04 on 2017/3/10. */ public class EndlessHorizontalScrollView extends HorizontalScrollView { private LinearLayout llData; private static final int MESSAGE_SCROLL = 10010; private static int offset = 1000; //滾動的時間間隔 private int pageSize, itemWidth, maxScrollWidth; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE_SCROLL: int scrollX = getScrollX(); int delay = 0; if (scrollX >= maxScrollWidth) { scrollTo(0, 0); } else { smoothScrollBy(itemWidth, 0); delay = offset; } postDelayed(new Runnable() { @Override public void run() { sendEmptyMessage(MESSAGE_SCROLL); } }, delay); break; } } }; public EndlessHorizontalScrollView(Context context) { this(context, null); } public EndlessHorizontalScrollView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public EndlessHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { llData = new LinearLayout(getContext()); llData.setOrientation(LinearLayout.HORIZONTAL); llData.setLayoutParams(new LayoutParams(-1, -1)); addView(llData); } public void setTextData(final List<String> data, final int pageSize) { post(new Runnable() { @Override public void run() { int containerWidth = getMeasuredWidth(); EndlessHorizontalScrollView.this.pageSize = pageSize; EndlessHorizontalScrollView.this.itemWidth = containerWidth / pageSize; EndlessHorizontalScrollView.this.maxScrollWidth = data.size() * itemWidth; data.addAll(data); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(itemWidth, -1); for (int i = 0; i < data.size(); i++) { TextView textView = new TextView(getContext()); textView.setTextColor(Utils.getColor(R.color.textcolor_normal)); textView.setGravity(Gravity.CENTER_VERTICAL); textView.setText(data.get(i)); textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); llData.addView(textView, params); } handler.postDelayed(new Runnable() { @Override public void run() { handler.sendEmptyMessage(MESSAGE_SCROLL); } }, offset); } }); } public void setImageData(final List<String> data, final int pageSize) { post(new Runnable() { @Override public void run() { int containerWidth = getMeasuredWidth(); EndlessHorizontalScrollView.this.pageSize = pageSize; EndlessHorizontalScrollView.this.itemWidth = containerWidth / pageSize; EndlessHorizontalScrollView.this.maxScrollWidth = data.size() * itemWidth; data.addAll(data); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(itemWidth, -1); for (int i = 0; i < data.size(); i++) { ImageView imageView = new ImageView(getContext()); String url = data.get(i); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); ImageLoader.getInstance().displayImage(url, imageView); llData.addView(imageView, params); } handler.postDelayed(new Runnable() { @Override public void run() { handler.sendEmptyMessage(MESSAGE_SCROLL); } }, offset); } }); } }
在相應的Activity中呼叫即可:
public class EndlessScrollViewActivity extends Activity { private EndlessScrollView esvNews; private EndlessHorizontalScrollView ehsvNews; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_endless_scrollview); esvNews = (EndlessScrollView) findViewById(R.id.esv_news); ehsvNews = (EndlessHorizontalScrollView) findViewById(R.id.ehsv_news); List<String> newsList = new ArrayList<>(); for(int i = 0; i < 10; i++) { newsList.add(String.valueOf(i)); } esvNews.setData(newsList, 3); List<String> imageUrls = new ArrayList<String>(); imageUrls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489140233265&di=1dc81ca9048383fede008b8e6a8bf50b&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fforum%2Fpic%2Fitem%2F4d5e27ed2e738bd447fa9de5a18b87d6257ff972.jpg"); imageUrls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489140245122&di=b5dc786d2e7379e637e3f07681d23ff7&imgtype=0&src=http%3A%2F%2Fa.hiphotos.baidu.com%2Fzhidao%2Fpic%2Fitem%2F72f082025aafa40f334b883fad64034f79f01946.jpg"); imageUrls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489140258012&di=07b5d545dfb2b14d44112c35e8673de0&imgtype=0&src=http%3A%2F%2Fwww.qqzhi.com%2Fuploadpic%2F2014-05-14%2F061226958.jpg"); imageUrls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489140849024&di=f32000dc7ac64e3140158cba302e32df&imgtype=0&src=http%3A%2F%2Ff0.topit.me%2F0%2F76%2F84%2F11545467533ed84760o.jpg"); imageUrls.add("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2397520815,2843221100&fm=23&gp=0.jpg"); imageUrls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489140884020&di=877664ad43c921f8ab7223b4b81315c4&imgtype=0&src=http%3A%2F%2Fc.hiphotos.baidu.com%2Fzhidao%2Fpic%2Fitem%2F6a600c338744ebf8f8b23843d9f9d72a6159a78f.jpg"); imageUrls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489140896008&di=b6d5b655fc1ec7e72f70f4634be3d2de&imgtype=0&src=http%3A%2F%2Fimg2.a0bi.com%2Fupload%2Fttq%2F20160110%2F1452399200997.jpg"); imageUrls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1489140915014&di=b032ce6bf87cc092507328d562722a71&imgtype=0&src=http%3A%2F%2Fb.hiphotos.baidu.com%2Fzhidao%2Fpic%2Fitem%2F5bafa40f4bfbfbed0ac552ba79f0f736aec31f52.jpg"); ehsvNews.setImageData(imageUrls, 3); } }
佈局檔案:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.jp04.myapplication.views.EndlessHorizontalScrollView android:layout_width="match_parent" android:layout_height="80dp" android:id="@+id/ehsv_news"/> <com.example.jp04.myapplication.views.EndlessScrollView android:layout_margin="10dp" android:layout_width="match_parent" android:layout_height="60dp" android:id="@+id/esv_news" /> </LinearLayout>