Android 实现无限滚动的ScrollView

用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;
import android.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>



猜你喜欢

转载自blog.csdn.net/qq_23934649/article/details/61200537