• 自定义轮播图CarouselView
  • 自定义下拉刷新PullRefreshListView

马上就要正式做毕业设计了,一些零碎时间写其中的一个模块,现记录下来,以备以后忘记时使用。欢迎大神不吝纠正。

效果图:

layout_carousel.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content">    <android.support.v4.view.ViewPager  android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="250dp">    </android.support.v4.view.ViewPager>    <LinearLayout  android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignBottom="@id/viewPager" android:background="#55000000" android:orientation="vertical" android:padding="10dp">        <TextView  android:id="@+id/tv_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:textColor="#fff" />        <LinearLayout  android:id="@+id/dot_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:gravity="center_horizontal" android:orientation="horizontal">        </LinearLayout>    </LinearLayout></RelativeLayout>

carousel_dot_selected.xml

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

carousel_dot_unselect.xml

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

carousel_dot_selector.xml (轮播图指示点选择器)

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@drawable/carousel_dot_selected" android:state_enabled="true" /> <item android:drawable="@drawable/carousel_dot_unselect" android:state_enabled="false" /></selector>

轮播图数据bean

package com.xing.carousel;/** * Created by Administrator on 2016/3/22. */public class CarouselData {    private int id;    private String title;    private int resId;    public CarouselData(int id, String title, int resId) {        this.id = id;        this.title = title;        this.resId = resId;    }    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }    public int getResId() {        return resId;    }    public void setResId(int resId) {        this.resId = resId;    }    @Override    public String toString() {        return "CarouselData{" +                "id=" + id +                ", title='" + title + '\'' +                ", resId=" + resId +                '}';    }}

自定义轮播图CarsouselView.java

package com.xing.carousel;import android.content.Context;import android.graphics.Color;import android.os.Handler;import android.os.Message;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 java.util.ArrayList;import java.util.List;/** * Created by Administrator on 2016/3/22. */public class CarouselView extends LinearLayout {    private Context context;    private List<CarouselData> carouselDataList;    private ViewPager viewPager;    private TextView tv_title;    private LinearLayout dotLayout;    private List<View> dotList;   //指示点    private static final int MSG_UPDATE = 1;    private Handler handler;    public CarouselView(Context context) {        this(context, null);    }    public CarouselView(Context context, AttributeSet attrs) {        super(context, attrs);        this.context = context;        init();    }    private void init() {        LayoutInflater.from(context).inflate(R.layout.layout_carousel, this, true);        initView();        initData();    }    private void initData() {        dotList = new ArrayList<>();    }    private void initView() {        viewPager = (ViewPager) findViewById(R.id.viewPager);        tv_title = (TextView) findViewById(R.id.tv_title);        dotLayout = (LinearLayout) findViewById(R.id.dot_layout);    }    public void start(List<CarouselData> carouselDataList) {        this.carouselDataList = carouselDataList;        if (this.carouselDataList == null || this.carouselDataList.size() < 1) {            return;        }        View view = null;        LayoutParams params = new LayoutParams(5, 5);        //根据轮播图要显示的数量来创建指示点的个数        for (int i = 0; i < this.carouselDataList.size(); i++) {            view = new View(context);            //设置dot的宽和高,相当于在xml中设置layout_height和layout_width            if (i != 0) {  //设置左边距                params.leftMargin = 5;            }            view.setLayoutParams(params);            view.setBackgroundResource(R.drawable.carousel_dot_selector);            dotList.add(view);  //加入到list集合中            dotLayout.addView(view);  //加入父布局        }        viewPager.setAdapter(new MyPagerAdapter());        viewPager.setOnPageChangeListener(new MyPagerChangeListener());        updateTitleDot();        if (handler == null) {            handler = new Handler() {                @Override                public void handleMessage(Message msg) {                    super.handleMessage(msg);                    switch (msg.what) {                        case MSG_UPDATE:                            int currentItem = viewPager.getCurrentItem();                            if (currentItem < CarouselView.this.carouselDataList.size() - 1) {  //从0开始                                currentItem++;                            } else {                                currentItem = 0;                            }                            viewPager.setCurrentItem(currentItem);                            handler.sendEmptyMessageDelayed(MSG_UPDATE, 2000);                            break;                    }                }            };            handler.sendEmptyMessageDelayed(MSG_UPDATE, 2000);        }    }    class MyPagerAdapter extends PagerAdapter {        @Override        public int getCount() {            return carouselDataList.size();        }        @Override        public boolean isViewFromObject(View view, Object object) {            return view == object;        }        @Override        public Object instantiateItem(ViewGroup container, final int position) {            final CarouselData carouselData = carouselDataList.get(position);            ImageView imageView = new ImageView(context);            imageView.setImageResource(carouselData.getResId());            imageView.setScaleType(ImageView.ScaleType.FIT_XY);            container.addView(imageView);            imageView.setOnClickListener(new OnClickListener() {                @Override                public void onClick(View view) {                    clickCallback.onClick(carouselData.getId(), position);                }            });            return imageView;        }        @Override        public void destroyItem(ViewGroup container, int position, Object object) {            container.removeView((View) object);        }    }    class MyPagerChangeListener implements ViewPager.OnPageChangeListener {        @Override        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {        }        @Override        public void onPageSelected(int position) {            updateTitleDot();        }        @Override        public void onPageScrollStateChanged(int state) {        }    }    private void updateTitleDot() {        int currentPosition = viewPager.getCurrentItem() % carouselDataList.size();        CarouselData carouselData = carouselDataList.get(currentPosition);        tv_title.setText(carouselData.getTitle());        for (int i = 0; i < carouselDataList.size(); i++) {            dotLayout.getChildAt(i).setEnabled(i == currentPosition);        }    }    ClickCallback clickCallback;    interface ClickCallback {        void onClick(int id, int position);    }    public void setClickCallback(ClickCallback clickCallback) {        this.clickCallback = clickCallback;    }}

圆形进度条
progressbar_rotate.xml

<?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:toDegrees="360">    <shape  android:innerRadius="12dp" android:shape="ring" android:thickness="3dp" android:useLevel="false">        <!--android:useLevel="false"用于禁止progressbar自己转圈,自己在外层套一个rotate,用于转圈-->        <gradient  android:centerColor="@color/progressbar_center_color" android:endColor="@color/progressbar_end_color" android:startColor="@color/progressbar_start_color" />    </shape></rotate>

下拉刷新控件

1.ListView头布局
layout_pull_listview_header.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="match_parent" android:gravity="center_horizontal" android:orientation="horizontal">    <!--android:padding不能使用,因为该布局将会以addHeaderview方式添加到listview,可用margin代替。-->    <FrameLayout  android:id="@+id/fl_progressbar_arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginBottom="8dp">        <ProgressBar  android:id="@+id/pb_refresh" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:indeterminateDrawable="@drawable/progressbar_rotate" android:visibility="invisible" />        <ImageView  android:id="@+id/iv_arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@mipmap/ic_pulltorefresh_arrow" />    </FrameLayout>    <LinearLayout  android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" android:gravity="center_horizontal" android:orientation="vertical">        <TextView  android:id="@+id/tv_listview_top_tip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="3dp" android:text="正在刷新" android:textColor="@color/colorPrimary" />        <TextView  android:id="@+id/tv_listview_top_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="3dp" android:text="最新刷新时间 2016-3-13" android:textColor="@color/colorPrimary" />    </LinearLayout></LinearLayout>

ListView底部布局
layout_pull_listview_footer.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:gravity="center" android:orientation="horizontal">    <ProgressBar  android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp" android:indeterminateDrawable="@drawable/progressbar_rotate" />    <TextView  android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginLeft="10dp" android:layout_marginTop="5dp" android:text="@string/loading_more" /></LinearLayout>

PullRefreshListView.java

package com.xing.carousel;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.animation.RotateAnimation;import android.widget.AbsListView;import android.widget.ImageView;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.TextView;import java.util.Date;/** * Created by Administrator on 2016/3/19. */public class PullRefreshListView extends ListView implements AbsListView.OnScrollListener {    private Context context;    private View headerView;    private final int STATE_PULL_REFRESH = 0;    private final int STATE_RELEASE_REFRESH = 1;    private final int STATE_REFRESHING = 2;    private int currentState = STATE_PULL_REFRESH;    private TextView mRefreshStatusTip;    private TextView mRefreshTime;    private ProgressBar mProgressBar;    private ImageView mArrowImg;    private int headerViewHeight;    private int startY = -1;   //初始值    private RotateAnimation upAnimation;    private RotateAnimation downAnimation;    private View footerView;    private int footerViewHeight;    public PullRefreshListView(Context context) {        this(context, null);    }    public PullRefreshListView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    private void init() {        context = getContext();        initView();        initData();    }    private void initData() {        //初始化头布局        headerView.measure(0, 0);        //得到头布局高度        headerViewHeight = headerView.getMeasuredHeight();        //设置上边距,隐藏头布局        headerView.setPadding(0, -headerViewHeight, 0, 0);        //将头布局添加至listView中        this.addHeaderView(headerView, null, false); //头布局selectable=false        //初始化底部布局数据        footerView.measure(0, 0);        footerViewHeight = footerView.getMeasuredHeight();        footerView.setPadding(0, 0, 0, -footerViewHeight);        this.addFooterView(footerView, null, false);        //初始化动画        initAnimation();    }    private void initView() {        //初始化listView头布局        headerView = View.inflate(context, R.layout.layout_pull_listview_header, null);        mProgressBar = (ProgressBar) headerView.findViewById(R.id.pb_refresh);        mArrowImg = (ImageView) headerView.findViewById(R.id.iv_arrow);        mRefreshStatusTip = (TextView) headerView.findViewById(R.id.tv_listview_top_tip);        mRefreshTime = (TextView) headerView.findViewById(R.id.tv_listview_top_time);        //初始化底部布局        footerView = View.inflate(context, R.layout.layout_pull_listview_footer, null);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                startY = (int) event.getRawY();                break;            case MotionEvent.ACTION_MOVE:                //如果当前正在刷新,则不处理                if (currentState == STATE_REFRESHING) {                    break;                }                if (startY == -1) {                    startY = (int) event.getRawY();   //保证startY有值                }                int deltaY = (int) (event.getRawY() - startY);  //手指移动的偏移量                if (deltaY > 0 && getFirstVisiblePosition() == 0) {  //只有手指向下滑动(deltaY>0)并且第一个item为可见的时候,才下拉刷新                    int paddingTop = -headerViewHeight + deltaY;                    headerView.setPadding(0, paddingTop, 0, 0);  //将更新的padding设置给headerview,实时更新下拉布局的位置                    if (paddingTop > 0 && currentState != STATE_RELEASE_REFRESH) {                        currentState = STATE_RELEASE_REFRESH;                        mArrowImg.startAnimation(upAnimation);                    } else if (paddingTop < 0 && currentState != STATE_PULL_REFRESH) {                        currentState = STATE_PULL_REFRESH;                        mArrowImg.startAnimation(downAnimation);                    }                    return true;  //拦截move事件,不让listview处理                }                break;            case MotionEvent.ACTION_UP:                startY = -1;  //重置                if (currentState == STATE_PULL_REFRESH) {  //手指抬起时,如果当前状态是下拉刷新,则直接隐藏头布局。                    headerView.setPadding(0, -headerViewHeight, 0, 0);                } else if (currentState == STATE_RELEASE_REFRESH) {   //手指抬起时,如果当前状态是松开刷新,则进入正在刷新状态                    currentState = STATE_REFRESHING;                    //显示正在刷新状态                    headerView.setPadding(0, 0, 0, 0);                    //更新当前状态                    refreshHeaderState(currentState);                    //监听回调                    if (onRefreshListener != null) {                        onRefreshListener.onRefresh();                    }                }                break;        }        return super.onTouchEvent(event);    }    private void refreshHeaderState(int currentState) {        switch (currentState) {            case STATE_PULL_REFRESH:                mRefreshStatusTip.setText(getResources().getString(R.string.state_pull_refresh));                mArrowImg.setVisibility(View.VISIBLE);                mProgressBar.setVisibility(View.INVISIBLE);                break;            case STATE_RELEASE_REFRESH:                mRefreshStatusTip.setText(getResources().getString(R.string.state_release_refresh));                mArrowImg.setVisibility(View.VISIBLE);                mProgressBar.setVisibility(View.INVISIBLE);                break;            case STATE_REFRESHING:                mRefreshStatusTip.setText(getResources().getString(R.string.state_refreshing));                mArrowImg.clearAnimation();  //清除动画才能设置其可见性                mArrowImg.setVisibility(View.INVISIBLE);                mProgressBar.setVisibility(View.VISIBLE);                mRefreshTime.setText(getResources().getString(R.string.last_refresh_time));                break;        }    }    private void initAnimation() {        //向上旋转动画        upAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f,                RotateAnimation.RELATIVE_TO_SELF, 0.5f);        upAnimation.setDuration(300);        upAnimation.setFillAfter(true);        //向下旋转动画        downAnimation = new RotateAnimation(-180, -360, RotateAnimation.RELATIVE_TO_SELF, 0.5f,                RotateAnimation.RELATIVE_TO_SELF, 0.5f);        downAnimation.setDuration(300);        downAnimation.setFillAfter(true);    }    /** * 重置headerview中的刷新状态和progressbar的显示 */    public void resetHeaderFooterView() {        currentState = STATE_PULL_REFRESH;        mRefreshStatusTip.setText(getResources().getString(R.string.state_pull_refresh));        mArrowImg.setVisibility(View.VISIBLE);        mProgressBar.setVisibility(View.INVISIBLE);    }    interface OnRefreshListener {        void onRefresh();        void loadMore();  //加载更多,通过listview的滚动监听实现    }    OnRefreshListener onRefreshListener;    public void setOnRefreshListener(OnRefreshListener onRefreshListener) {        this.onRefreshListener = onRefreshListener;    }    /** * ListView的滑动监听 * * @param view * @param scrollState */    @Override    public void onScrollStateChanged(AbsListView view, int scrollState) {        if (scrollState == OnScrollListener.SCROLL_STATE_FLING || scrollState == OnScrollListener.SCROLL_STATE_IDLE) {            if (getLastVisiblePosition() == getCount() - 1) {   //滑动到最后一条,显示tooterView                footerView.setPadding(0, 0, 0, 0);                setSelection(getCount() - 1);  //将最后一条拉到屏幕中显示,这样,footerview就可以显示出来了,否则,footerview需要再次滑动才能显示在屏幕中            }        }    }    @Override    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {    }}

新建Android Project 测试demo

<?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:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.xing.carousel.MainActivity">    <com.xing.carousel.PullRefreshListView  android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" /></LinearLayout>

轮播图作为头布局添加到PullRefreshListView中
layout_header.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">    <com.xing.carousel.CarouselView  android:id="@+id/carsouelView" android:layout_width="match_parent" android:layout_height="wrap_content" /></LinearLayout>

MainActivity.java

package com.xing.carousel;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.ArrayAdapter;import android.widget.ListView;import android.widget.Toast;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {    private CarouselView carouselView;    private List<CarouselData> carouselDataList;    private PullRefreshListView listView;    private int[] resIds = {R.mipmap.ic_launcher, R.mipmap.top2, R.mipmap.back2};    private List<String> data;    private View headerView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        listView = (PullRefreshListView) findViewById(R.id.listView);        headerView = View.inflate(this, R.layout.layout_header, null);        carouselView = (CarouselView) headerView.findViewById(R.id.carsouelView);        carouselDataList = new ArrayList<>();        for (int i = 0; i < resIds.length; i++) {            carouselDataList.add(new CarouselData(i, "标题" + i, resIds[i]));        }        carouselView.start(carouselDataList);        data = new ArrayList<>();        for (int i = 0; i < 10; i++) {            data.add("ListView---->" + i);        }        listView.addHeaderView(headerView);        listView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, data));        carouselView.setClickCallback(new CarouselView.ClickCallback() {            @Override            public void onClick(int id, int position) {                Toast.makeText(MainActivity.this, "你点击了第" + position + "项", Toast.LENGTH_SHORT).show();            }        });    }}

更多相关文章

  1. 手机 web 开发工作经验
  2. This tag and its children can be replaced by ~~~
  3. android之RadioButton设置setChecked(true)失效
  4. Android培训班(110)start_kernel函数7
  5. android添加常驻图标到状态栏
  6. Android(安卓)intent传递hashMap对象,遍历hashMap,改变menu状态
  7. Android(安卓)APP 启动优化(冷启动)
  8. android软键盘遮挡布局
  9. android用MediaCodeC将opengl绘制内容录制为一个mp4

随机推荐

  1. go语言有指针吗
  2. go语言是啥
  3. go属于解释型语言么
  4. go语言defer的用法是什么
  5. go语言有几种框架
  6. windows下怎么搭建go语言开发环境
  7. go语言如何将大写转小写
  8. go语言的优势有哪些
  9. go语言适合用在哪方面
  10. mac怎么搭建go语言开发环境