当前位置: 搜索的结果

功能强大的StickyHeaderListView

功能强大的StickyHeaderListView:标题渐变、吸附悬停、筛选分类、动态头部等

来自:https://github.com/sfsheng0322/StickyHeaderListView

listview下拉刷新仿最新版美团外卖

/** * 初始化view * * @param context */ private void init(Context context) { setOverScrollMode(View.OVER_SCROLL_NEVER); setOnScrollListener(this); headerView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.listview_head_view, null, false); footerView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.listview_foot_view, null, false); tv_load = (TextView) footerView.findViewById(R.id.tv_load); bg_view= (RefreshBgView) headerView.findViewById(R.id.bg_view); bg_view.setBackgroundResource(R.drawable.loading_bg1); bg_viewAnimation = (AnimationDrawable) bg_view.getBackground(); bg_viewAnimation.start(); refreshAnimView = (RefreshAnimView) headerView.findViewById(R.id.first_step_view); refreshLoadingView= (RefreshLoadingView) headerView.findViewById(R.id.second_step_view); refreshLoadingView.setBackgroundResource(R.drawable.anim_refresh); loadAnimation = (AnimationDrawable) refreshLoadingView.getBackground(); measureView(headerView); measureView(footerView); addHeaderView(headerView); addFooterView(footerView); headerViewHeight = headerView.getMeasuredHeight(); footerViewHeight = footerView.getMeasuredHeight(); headerView.setPadding(0, -headerViewHeight, 0, 0); footerView.setPadding(0, 0, 0, -footerViewHeight); refreshstate = REFRESH_DONE; loadstate = LOAD_DONE; isRefreshable = true; isLoadable = true; }

listview播放视频和点击每一个适配进去全屏模式

listview播放视频和点击每一个适配进去全屏模式,全屏切换效果不错,适合初学者研究,感觉同学分享。

(静态图不能展示完整的效果,望谅解,感兴趣的朋友自行下载研究探讨)

CircularLayout 实现listview水平叠加图片效果

CircularLayout 实现listview水平叠加图片效果,可以动态调整item之间水平间距,
点击某一个item有选择效果,适合做菜单效果的。可以动态调节圆角弧度。
项目来自:https://github.com/xuandoutang/CircularLayout

 

高仿ios消息列表滑动效果,listview

模仿iOS7短信界面的滑滑的惯性动画效果 ,使用:像普通 ListView 那样用就好了
本项目来源:https://github.com/kot32go/iOSMessageLi
项目主要介绍:
通过自定义iOSMessageList,继承ListView,监听listview 的滚动事件OnScrollListener,
在onScroll中调用如下动画实现的。

    private void startAnimation(final int firstIndex, final int lastIndex) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i < lastIndex - firstIndex; i++) {
                    View child = getChildAt(i);
                    if (isScrollToUp) {
                        child = getChildAt(lastIndex - firstIndex - i);
                    }
                    Message message = new Message();
                    message.what = START_ANIMATION;
                    message.obj = child;
                    message.arg1 = i;
                    message.arg2 = lastIndex - firstIndex - i;

                    animationHandler.sendMessage(message);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        }).start();


    }

仿京东商城下拉刷新RefreshListView

仿京东商城下拉刷新RefreshListView,下拉的时候小人跑步加载效果,
本项目来自:https://github.com/nugongshou110/JingDongRefreshListView
主要由如下代码绘画的:
/**
     * 绘制方法
     * @param canvas
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //由于包裹和快递小哥要分别来画,所以使用save和restore方法
        //save
        //画包裹
        //restore
        //save
        //画小哥
        //restore
        canvas.save();
        canvas.scale(mCurrentProgress, mCurrentProgress ,  measuredWidth-scaledGoods.getWidth()/2 , measuredHeight/2);
        mPaint.setAlpha(mCurrentAlpha);
        canvas.drawBitmap(scaledGoods, measuredWidth-scaledGoods.getWidth(), measuredHeight/2-scaledGoods.getHeight()/2, mPaint);
        canvas.restore();
        canvas.save();
        canvas.scale(mCurrentProgress, mCurrentProgress , 0 , measuredHeight/2);
        mPaint.setAlpha(mCurrentAlpha);
        canvas.drawBitmap(scaledPeople, 0,0,mPaint);
        canvas.restore();
    }

 

MeiTuanRefreshListView高仿美团下拉刷新

MeiTuanRefreshListView高仿美团下拉刷新,
本项目来自:https://github.com/nugongshou110/MeiTuanRefreshListView
项目主要构成部分:自定义MeiTuanRefreshFirstStepView,MeiTuanRefreshSecondStepView,
MeiTuanRefreshThirdStepView,其中自定义MeiTuanListView 继承了ListView实现的,
部分代码如下:
public class MeiTuanListView extends ListView implements AbsListView.OnScrollListener{
    private static final int DONE = 0;
    private static final int PULL_TO_REFRESH = 1;
    private static final int RELEASE_TO_REFRESH = 2;
    private static final int REFRESHING = 3;
    private static final int RATIO = 3;
    private LinearLayout headerView;
    private int headerViewHeight;
    private float startY;
    private float offsetY;
    private TextView tv_pull_to_refresh;
    private OnMeiTuanRefreshListener mOnRefreshListener;
    private int state;
    private int mFirstVisibleItem;
    private boolean isRecord;
    private boolean isEnd;
    private boolean isRefreable;
    private FrameLayout mAnimContainer;
    private Animation animation;
    private SimpleDateFormat format;
    private MeiTuanRefreshFirstStepView mFirstView;
    private MeiTuanRefreshSecondStepView mSecondView;
    private AnimationDrawable secondAnim;
    private MeiTuanRefreshThirdStepView mThirdView;
    private AnimationDrawable thirdAnim;

    public MeiTuanListView(Context context) {
        super(context);
        init(context);
    }

    public MeiTuanListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public MeiTuanListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public interface OnMeiTuanRefreshListener{
        void onRefresh();
    }
    public void setOnMeiTuanRefreshListener(OnMeiTuanRefreshListener onRefreshListener){
        mOnRefreshListener = onRefreshListener;
        isRefreable = true;
    }
    public void setOnRefreshComplete(){
        isEnd = true;
        state = DONE;
        
        changeHeaderByState(state);
    }

    private void init(Context context) {
        setOverScrollMode(View.OVER_SCROLL_NEVER);
        setOnScrollListener(this);
        
        headerView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.meituan_item, null, false);
        mFirstView = (MeiTuanRefreshFirstStepView) headerView.findViewById(R.id.first_view);
        tv_pull_to_refresh = (TextView) headerView.findViewById(R.id.tv_pull_to_refresh);
        mSecondView = (MeiTuanRefreshSecondStepView) headerView.findViewById(R.id.second_view);
        mSecondView.setBackgroundResource(R.drawable.pull_to_refresh_second_anim);
        secondAnim = (AnimationDrawable) mSecondView.getBackground();
        mThirdView = (MeiTuanRefreshThirdStepView) headerView.findViewById(R.id.third_view);
        mThirdView.setBackgroundResource(R.drawable.pull_to_refresh_third_anim);
        thirdAnim = (AnimationDrawable) mThirdView.getBackground();
        
        measureView(headerView);
        addHeaderView(headerView);
        headerViewHeight = headerView.getMeasuredHeight();
        headerView.setPadding(0, -headerViewHeight, 0, 0);
        Log.i("zhangqi","headerViewHeight="+headerViewHeight);

        state = DONE;
        isEnd = true;
        isRefreable = false;
    }
    

 

    @Override
    public void onScrollStateChanged(AbsListView absListView, int i) {
    }
    @Override
    public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        mFirstVisibleItem = firstVisibleItem;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (isEnd) {
            if (isRefreable) {
                switch (ev.getAction()){
                case MotionEvent.ACTION_DOWN:
                    if (mFirstVisibleItem == 0 && !isRecord) {
                        isRecord = true;
                        startY = ev.getY();
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    float tempY = ev.getY();
                    if (mFirstVisibleItem == 0 && !isRecord) {
                        isRecord = true;
                        startY = tempY;
                    }
                    if (state!=REFRESHING && isRecord ) {
                        offsetY = tempY - startY;
                        float currentHeight = (-headerViewHeight+offsetY/3);
                        float currentProgress = 1+currentHeight/headerViewHeight;
                        if (currentProgress>=1) {
                            currentProgress = 1;
                        }
                        if (state == RELEASE_TO_REFRESH && isRecord) {
                            setSelection(0);
                            if (-headerViewHeight+offsetY/RATIO<0) {
                                state = PULL_TO_REFRESH;
                                changeHeaderByState(state);
                            }else if (offsetY<=0) {
                                state = DONE;
                                changeHeaderByState(state);
                            }
                        }
                        if (state == PULL_TO_REFRESH && isRecord) {
                            setSelection(0);
                            if (-headerViewHeight+offsetY/RATIO>=0) {
                                state = RELEASE_TO_REFRESH;
                                changeHeaderByState(state);
                            }else if (offsetY<=0) {
                                state = DONE;
                                changeHeaderByState(state);
                            }
                        }
                        if (state == DONE && isRecord) {
                            if (offsetY>=0) {
                                state = PULL_TO_REFRESH;
                            }
                        }
                        if (state == PULL_TO_REFRESH) {
                            headerView.setPadding(0,(int)(-headerViewHeight+offsetY/RATIO) ,0,0);
                            mFirstView.setCurrentProgress(currentProgress);
                            mFirstView.postInvalidate();
                        }
                        if (state == RELEASE_TO_REFRESH) {
                            headerView.setPadding(0,(int)(-headerViewHeight+offsetY/RATIO) ,0, 0);
                            mFirstView.setCurrentProgress(currentProgress);
                            mFirstView.postInvalidate();
                        }
                    }
                
                    
                    break;
                case MotionEvent.ACTION_UP:
                    if (state == PULL_TO_REFRESH) {
                        this.smoothScrollBy((int)(-headerViewHeight+offsetY/RATIO)+headerViewHeight, 500);
                        changeHeaderByState(state);
                    }
                    if (state == RELEASE_TO_REFRESH) {
                        this.smoothScrollBy((int)(-headerViewHeight+offsetY/RATIO), 500);
                        state = REFRESHING;
                        mOnRefreshListener.onRefresh();
                        changeHeaderByState(state);
                    }
                    isRecord = false;
                    break;
                }
                
            }
        }
        return super.onTouchEvent(ev);
    }
    
    private void changeHeaderByState(int state){
        switch (state) {
        case DONE:
            headerView.setPadding(0, -headerViewHeight, 0, 0);
            mFirstView.setVisibility(View.VISIBLE);
            mSecondView.setVisibility(View.GONE);
            secondAnim.stop();
            mThirdView.setVisibility(View.GONE);
            thirdAnim.stop();
            break;
        case RELEASE_TO_REFRESH:
            tv_pull_to_refresh.setText("放开刷新");
            mFirstView.setVisibility(View.GONE);
            mSecondView.setVisibility(View.VISIBLE);
            secondAnim.start();
            mThirdView.setVisibility(View.GONE);
            thirdAnim.stop();
            break;
        case PULL_TO_REFRESH:
            tv_pull_to_refresh.setText("下拉刷新");
            state = DONE;
            mFirstView.setVisibility(View.VISIBLE);
            mSecondView.setVisibility(View.GONE);
            secondAnim.stop();
            mThirdView.setVisibility(View.GONE);
            thirdAnim.stop();
            break;
        case REFRESHING:
            tv_pull_to_refresh.setText("正在刷新");
            mFirstView.setVisibility(View.GONE);
            mThirdView.setVisibility(View.VISIBLE);
            mSecondView.setVisibility(View.GONE);
            secondAnim.stop();
            thirdAnim.start();
            break;
        default:
            break;
        }
    }
    
    
    private void measureView(View child) {
        ViewGroup.LayoutParams p = child.getLayoutParams();
        if (p == null) {
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
        int lpHeight = p.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
                    MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0,
                    MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }


}

 

//如何调用呢

    mDatas = new ArrayList<String>(Arrays.asList(data));
        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,mDatas);
        mListView.setAdapter(mAdapter);
        mListView.setOnMeiTuanRefreshListener(this);

 

AutoHomeRefreshListView仿汽车之家下拉刷新

AutoHomeRefreshListView 高仿汽车之家下拉刷新 ,下拉的时候出现很不错的效果。
本项目来自:https://github.com/nugongshou110/AutoHomeRefreshListView
首先是自定义AutoHomeListView,继承ListView实现的
重要代码如下:

public class AutoHomeListView extends ListView implements AbsListView.OnScrollListener{
    private static final int DONE = 0;
    private static final int PULL_TO_REFRESH = 1;
    private static final int RELEASE_TO_REFRESH = 2;
    private static final int REFRESHING = 3;
    private static final int RATIO = 4;
    private LinearLayout headerView;
    private AutoHome mAutoHome;
    private int headerViewHeight;
    private float startY;
    private float currentProgress;
    private int currentHeight;
    private float offsetY;
    private TextView tv_pull_to_refresh;
    private OnAutoHomeRefreshListener mOnRefreshListener;
    private int state;
    private int mFirstVisibleItem;
    private boolean isRecord;
    private boolean isEnd;
    private boolean isRefreable;
    private FrameLayout mAnimContainer;
    private PointerView mAutoHomeAnim;
    private Animation animation;


    public AutoHomeListView(Context context) {
        super(context);
        init(context);
    }

    public AutoHomeListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public AutoHomeListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public interface OnAutoHomeRefreshListener{
        void onRefresh();
    }
    public void setOnAutoHomeRefreshListener(OnAutoHomeRefreshListener onRefreshListener){
        mOnRefreshListener = onRefreshListener;
        isRefreable = true;
    }
    public void setOnRefreshComplete(){
        isEnd = true;
        state = DONE;
        changeHeaderByState(state);
    }

    private void init(Context context) {
        setOverScrollMode(View.OVER_SCROLL_NEVER);
        setOnScrollListener(this);
        
        headerView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.autohome_item, null, false);
        mAutoHome = (AutoHome) headerView.findViewById(R.id.auto_home);
        tv_pull_to_refresh = (TextView) headerView.findViewById(R.id.tv_pull_to_refresh);
        mAnimContainer = (FrameLayout) headerView.findViewById(R.id.anim_container);
        mAutoHomeAnim = (PointerView) headerView.findViewById(R.id.anim_pointer);
        
        animation = AnimationUtils.loadAnimation(context, R.anim.pointer_rotate);
        
        measureView(headerView);
        addHeaderView(headerView);
        headerViewHeight = headerView.getMeasuredHeight();
        headerView.setPadding(0, -headerViewHeight, 0, 0);

        state = DONE;
        isEnd = true;
        isRefreable = false;
    }

 

    @Override
    public void onScrollStateChanged(AbsListView absListView, int i) {
    }
    @Override
    public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        mFirstVisibleItem = firstVisibleItem;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (isEnd) {
            if (isRefreable) {
                switch (ev.getAction()){
                case MotionEvent.ACTION_DOWN:
                    if (mFirstVisibleItem == 0 && !isRecord) {
                        isRecord = true;
                        startY = ev.getY();
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    float tempY = ev.getY();
                    if (mFirstVisibleItem == 0 && !isRecord) {
                        isRecord = true;
                        startY = tempY;
                    }
                    if (state!=REFRESHING && isRecord ) {
                        offsetY = tempY - startY;
                        float currentHeight = (-headerViewHeight+offsetY/3);
                        float currentProgress = 1+currentHeight/headerViewHeight;
                        if (currentProgress>=1) {
                            currentProgress = 1;
                        }
                        if (state == RELEASE_TO_REFRESH && isRecord) {
                            setSelection(0);
                            if (-headerViewHeight+offsetY/3<0) {
                                state = PULL_TO_REFRESH;
                                changeHeaderByState(state);
                            }else if (offsetY<=0) {
                                state = DONE;
                                changeHeaderByState(state);
                            }
                        }
                        if (state == PULL_TO_REFRESH && isRecord) {
                            setSelection(0);
                            if (-headerViewHeight+offsetY/3>=0) {
                                state = RELEASE_TO_REFRESH;
                                changeHeaderByState(state);
                            }else if (offsetY<=0) {
                                state = DONE;
                                changeHeaderByState(state);
                            }
                        }
                        if (state == DONE && isRecord) {
                            if (offsetY>=0) {
                                state = PULL_TO_REFRESH;
                            }
                        }
                        if (state == PULL_TO_REFRESH) {
                            Log.i("zhangqi", ""+(int)(-headerViewHeight+offsetY/3));
                            headerView.setPadding(0,(int)(-headerViewHeight+offsetY/3) ,0,0);
                            mAutoHome.setCurrentProgress(currentProgress);
                            mAutoHome.postInvalidate();
                        }
                        if (state == RELEASE_TO_REFRESH) {
                            headerView.setPadding(0,(int)(-headerViewHeight+offsetY/3) ,0, 0);
                            mAutoHome.setCurrentProgress(currentProgress);
                            mAutoHome.postInvalidate();
                        }
                    }
                
                    
                    break;
                case MotionEvent.ACTION_UP:
                    if (state == PULL_TO_REFRESH) {
                        this.smoothScrollBy((int)(-headerViewHeight+offsetY/3)+headerViewHeight, 500);
                        changeHeaderByState(state);
                    }
                    if (state == RELEASE_TO_REFRESH) {
                        this.smoothScrollBy((int)(-headerViewHeight+offsetY/3), 500);
                        state = REFRESHING;
                        mOnRefreshListener.onRefresh();
                        changeHeaderByState(state);
                    }
                    isRecord = false;
                    break;
                }
                
            }
        }
        return super.onTouchEvent(ev);
    }
    
    private void changeHeaderByState(int state){
        switch (state) {
        case DONE:
            headerView.setPadding(0, -headerViewHeight, 0, 0);
            mAutoHome.setVisibility(View.VISIBLE);
            mAutoHomeAnim.clearAnimation();
            mAnimContainer.setVisibility(View.GONE);
            break;
        case RELEASE_TO_REFRESH:
            tv_pull_to_refresh.setText("放开刷新");
        
            break;
        case PULL_TO_REFRESH:
            tv_pull_to_refresh.setText("下拉刷新");
            state = DONE;
            mAutoHome.setVisibility(View.VISIBLE);
            mAutoHomeAnim.clearAnimation();
            mAnimContainer.setVisibility(View.GONE);
            break;
        case REFRESHING:
            tv_pull_to_refresh.setText("正在刷新");
            mAutoHome.setVisibility(View.GONE);
            mAnimContainer.setVisibility(View.VISIBLE);
            mAutoHomeAnim.clearAnimation();
            mAutoHomeAnim.startAnimation(animation);
            break;
        default:
            break;
        }
    }
    
    
    private void measureView(View child) {
        ViewGroup.LayoutParams p = child.getLayoutParams();
        if (p == null) {
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
        int lpHeight = p.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
                    MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0,
                    MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }


}


//如何调用
        mAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,mDatas);
        mListView = (AutoHomeListView) findViewById(R.id.listview);
        mListView.setAdapter(mAdapter);
        mListView.setOnAutoHomeRefreshListener(this);

 

listview实现各种版面设计功能

本项目主要listview实现各种版面设计功能,有实现列表的,gridview效果的,有混排效果的等等。
自定义TwoWayView继承RecyclerView,通过TwoWayView去根据布局实现到底选择哪一个效果,
本项目来自:https://github.com/lucasr/twoway-view
listview代码部分:
<org.lucasr.twowayview.widget.TwoWayView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    style="@style/TwoWayView"
    app:twowayview_layoutManager="ListLayoutManager"/>

实现gradview效果:
<org.lucasr.twowayview.widget.TwoWayView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    style="@style/TwoWayView"
    app:twowayview_layoutManager="GridLayoutManager"
    app:twowayview_numColumns="3"
    app:twowayview_numRows="3" />

实现混排效果:
<org.lucasr.twowayview.widget.TwoWayView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    style="@style/TwoWayView"
    app:twowayview_layoutManager="StaggeredGridLayoutManager"
    app:twowayview_numColumns="2"
    app:twowayview_numRows="2" />

 

android listview中item通过viewpager实现

android listview中item通过viewpager实现,每一个item都支持viewpager实现图片切换功能。本项目主要介绍多个viewpager加载图片和listview 上下滑动不卡顿问题。本项目由作者Flyco分享的
分享地址:https://github.com/H07000223/FlycoBanner_Master。
本项目找对应id封装一个ViewFindUtils类,通过如下代码找id
    /**
     * 替代findviewById方法
     */
    public static <T extends View> T find(View view, int id)
    {
        return (T) view.findViewById(id);
    }

查找调用:
        ViewFindUtils.find(decorView, R.id.tv_select_transformer).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSelectDialog(false);
            }
        });