Android使用自定义控件实现加载网络图片无限轮播

MainActivity

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity {

    private Carousel c;
    private List<CarouselData> data;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initControl();
        //开启轮播控件
        data = new ArrayList<CarouselData>();
        String[] urls = new String[]{
                "http://7xlwwd.com1.z0.glb.clouddn.com/yanwushu1.jpg",
                "http://7xlwwd.com1.z0.glb.clouddn.com/yanwushu2.jpg",
                "http://7xlwwd.com1.z0.glb.clouddn.com/yanwushu3.jpg"
        };
        for (int i = 0; i < urls.length; i++) {
            CarouselData d = new CarouselData();
            d.setImage(urls[i]);
            d.setTitle("测试tile" + i);
            d.setId(i);
            data.add(d);
        }
        c.startup(data);
    }

    private void initControl() {
        c = (Carousel) findViewById(R.id.crs);
        c.setCallback(new Carousel.ClickCallback() {
            @Override
            public void perform(int id, int position) {
                Toast.makeText(MainActivity.this, "id:" + id + "position" + position + "title:" + data.get(position).getTitle(), Toast.LENGTH_LONG).show();
            }
        });
    }

    @Override
    protected void onStop() {
        super.onStop();
        c.shutdown();
    }
}

Carousel

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
import com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by peng on 2015/9/19.
 * 图片轮播控件
 * 特性及使用方式如下:
 * 1.此组件extends linearLayout,意味着可以随意嵌入到任何布局文件中
 * 2.轮播的帧数(组件下方点数量)随着提供数据量(adlist.getSize())动态指定
 * 3.使用startup(List<AdList>)方法启动此组件,使用shutdown方法停止此组件的轮播动作
 * 4.使用回调函数指定点击之后的处理逻辑
 */
public class Carousel extends LinearLayout {

    //默认图片缓存路径,可以通过setter进行设置,默认如下值
    private String imageCachePath = "imageloader/Cache";

    //region fileds
    private Context context;
    private ViewPager viewPager;
    private List<ImageView> imageViews;// 滑动的图片集合
    private List<View> dots; //标识当前图片的点
    private TextView tv_title;
    private int currentItem = 0; // 当前图片的索引
    private LinearLayout dotWraper;
    private ScheduledExecutorService scheduledExecutorService;

    // 异步加载图片
    private ImageLoader imgLoader;
    private DisplayImageOptions options;

    //轮播数据源
    private List<CarouselData> data;

    private Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            viewPager.setCurrentItem(currentItem);
        }
    };

    private ClickCallback callback;
    //endregion

    public Carousel(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        LayoutInflater.from(context).inflate(R.layout.carousel, this, true);
    }

    private void initImageLoader() {
        options = new DisplayImageOptions.Builder()
                .showStubImage(R.drawable.bg)
                .showImageForEmptyUri(R.drawable.bg)
                .showImageOnFail(R.drawable.bg)
                .cacheInMemory(true).cacheOnDisc(true)
                .bitmapConfig(Bitmap.Config.RGB_565)
                .imageScaleType(ImageScaleType.EXACTLY).build();
        imgLoader = ImageLoader.getInstance();
        File cacheDir = com.nostra13.universalimageloader.utils.StorageUtils
                .getOwnCacheDirectory(context.getApplicationContext(),
                        imageCachePath);
        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
                .cacheInMemory(true).cacheOnDisc(true).build();
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
                .defaultDisplayImageOptions(defaultOptions)
                .memoryCache(new LruMemoryCache(12 * 1024 * 1024))
                .memoryCacheSize(12 * 1024 * 1024)
                .discCacheSize(32 * 1024 * 1024).discCacheFileCount(100)
                .discCache(new UnlimitedDiscCache(cacheDir))
                .threadPriority(Thread.NORM_PRIORITY - 2)
                .tasksProcessingOrder(QueueProcessingType.LIFO).build();
        imgLoader.init(config);
    }

    private void initControl() {
        initImageLoader();
        imageViews = new ArrayList<ImageView>();
        tv_title = (TextView) findViewById(R.id.tv_title);
        viewPager = (ViewPager) findViewById(R.id.vp);
    }

    private void addDynamicView() {
        // 动态添加图片和下面指示的圆点
        // 初始化图片资源
        if (null == data || data.size() < 1)
            return;
        for (int i = 0; i < data.size(); i++) {
            ImageView imageView = new ImageView(context);
            // 异步加载图片
            imgLoader.displayImage(data.get(i).getImage(), imageView,
                    options);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageViews.add(imageView);
            dots.get(i).setVisibility(View.VISIBLE);
        }
    }

    private void start() {
        scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        // 每两秒切换一次图片显示
        scheduledExecutorService.scheduleAtFixedRate(new ScrollTask(), 1, 2,
                TimeUnit.SECONDS);
    }

    private class ScrollTask implements Runnable {
        @Override
        public void run() {
            synchronized (viewPager) {
                currentItem = (currentItem + 1) % imageViews.size();
                handler.obtainMessage().sendToTarget();
            }
        }
    }

    private class MyPageChangeListener implements ViewPager.OnPageChangeListener {

        private int oldPosition = 0;

        @Override
        public void onPageScrollStateChanged(int arg0) {

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {

        }

        @Override
        public void onPageSelected(int position) {
            currentItem = position;
            if (null == data || data.size() < 1)
                return;
            CarouselData ad = data.get(position);
            tv_title.setText(ad.getTitle());
            dots.get(oldPosition).setBackgroundResource(R.drawable.dot_normal);
            dots.get(position).setBackgroundResource(R.drawable.dot_focused);
            oldPosition = position;
        }
    }

    private class MyPagerAdapter extends PagerAdapter {
        @Override
        public int getCount() {
            return data.size();
        }

        @Override
        public Object instantiateItem(ViewGroup container, final int position) {
            ImageView iv = imageViews.get(position);
            ((ViewPager) container).addView(iv);
            final CarouselData dataItem = data.get(position);
            iv.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (callback != null) {
                        callback.perform(dataItem.getId(), position);
                    }
                }
            });
            return iv;
        }

        @Override
        public void destroyItem(View arg0, int arg1, Object arg2) {
            ((ViewPager) arg0).removeView((View) arg2);
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }

        @Override
        public void restoreState(Parcelable arg0, ClassLoader arg1) {

        }

        @Override
        public Parcelable saveState() {
            return null;
        }
    }

    //启动
    public void startup(List<CarouselData> adList) {
        initControl();
        this.data = adList;
        dotWraper = (LinearLayout) findViewById(R.id.dot_wraper);
        dots = new ArrayList<View>();
        for (int i = 0; i < adList.size(); i++) {
            View dot = LayoutInflater.from(context).inflate(R.layout.carousel_dot, this, false);
            dots.add(dot);
            dotWraper.addView(dot);
        }
        addDynamicView();
        viewPager.setAdapter(new MyPagerAdapter());
        viewPager.setOnPageChangeListener(new MyPageChangeListener());
        start();
    }

    //停止此控件的轮播
    public void shutdown() {
        if (scheduledExecutorService != null)
            scheduledExecutorService.shutdown();
    }

    interface ClickCallback {
        public void perform(int id, int position);
    }

    //region getter and setter
    public String getImageCachePath() {
        return imageCachePath;
    }

    public void setImageCachePath(String imageCachePath) {
        this.imageCachePath = imageCachePath;
    }

    public void setCallback(ClickCallback callback) {
        this.callback = callback;
    }
    //endregion
}

CarouselData

/**
 * Created by Administrator on 2015/8/17.
 */
public class CarouselData {

    private int Id;
    private String Title;
    private String Image;
    private int PositionId;


    //region getter and setter
    public int getId() {
        return Id;
    }

    public void setId(int id) {
        Id = id;
    }

    public String getTitle() {
        return Title;
    }

    public void setTitle(String title) {
        Title = title;
    }

    public String getImage() {
        return Image;
    }

    public void setImage(String image) {
        Image = image;
    }

    public int getPositionId() {
        return PositionId;
    }

    public void setPositionId(int positionId) {
        PositionId = positionId;
    }
    //endregion
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scrollbars="none">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#FFFFFF"
        android:orientation="vertical">

        <pzh.com.carousel.Carousel
            android:id="@+id/crs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
</ScrollView>

carousel.xml

<?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="wrap_content"
    android:orientation="vertical">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="210dp">

        <android.support.v4.view.ViewPager
            android:id="@+id/vp"
            android:layout_width="match_parent"
            android:layout_height="210dp" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:background="@drawable/shadow_article">

            <RelativeLayout
                android:id="@+id/author_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_marginLeft="10dp"
                android:gravity="center_vertical"
                android:paddingBottom="20dp">

                <TextView
                    android:id="@+id/tv_title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:textColor="#fff"
                    android:textSize="15sp" />

                <TextView
                    android:id="@+id/tv_date"
                    android:layout_width="wrap_content"
                    android:layout_toRightOf="@id/tv_title"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:paddingTop="3dp"
                    android:textColor="#fff"
                    android:textSize="12sp" />
            </RelativeLayout>
        </RelativeLayout>

        <LinearLayout
            android:id="@+id/dot_wraper"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            android:layout_marginBottom="10dp"
            android:layout_marginTop="10dip"
            android:orientation="horizontal"
            android:gravity="center">

        </LinearLayout>
    </FrameLayout>

</LinearLayout>

carousel_dot.xml

<?xml version="1.0" encoding="utf-8"?>

<View xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/dot_style"
    android:background="@drawable/dot_focused"
    android:visibility="invisible" />

在Drawable文件夹下创建 dot_focused.xml 和 dot_normal.xml

dot_focused.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >

    <solid android:color="#aaFFFFFF" />

    <corners android:radius="5dip" />

</shape>

dot_normal.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >

    <solid android:color="#33000000" />

    <corners android:radius="5dip" />

</shape>


素材:

bg.jpg







shadow_article.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值