1. 程式人生 > >新手自定義控制元件,建立屬於自己的下拉重新整理(一)---Android,ListView實現IOS的彈性效果

新手自定義控制元件,建立屬於自己的下拉重新整理(一)---Android,ListView實現IOS的彈性效果

前言

相信很多童鞋對於控制元件的下拉重新整理都比較熟悉吧,常用的PullToRefresh開源庫和Google自帶的SwipeRefreshLayout大家肯定也很熟悉吧,但作為一個Android開發新手,對於自定義控制元件和自定義View來實現一些效果肯定還是比較恐懼,無從下手,筆者也是如此.但萬事開頭難,只要理清楚想要實現的效果,按照步驟來分佈來具體程式碼實施就OK了.
其實下拉重新整理,感覺萬變不離其宗,對普通的下拉重新整理有很多可以延伸的地方,比如:帶幀動畫的下拉重新整理.美團,大眾點評,汽車之家.從listview延伸到所有控制元件的下拉重新整理.筆者近期想要實現的就是ViewPager左右滑動重新整理載入帶彈性的效果

.筆者打算通過幾篇日誌來記錄整個實現過程,供各位參考.

效果

本文想要實現的效果是,Android中的ListView下拉的時候有彈性的效果,類似IOS的ListView,但與IOS不一樣,android想要實現這一的效果需要重寫Listview.我們先來看看效果圖,如下:
這裡寫圖片描述

實現思路

我們想要的目的清楚了,然後就是具體實現思路.
核心:在ListView的頂部增加一個headView.並且在下拉的過程中動態改變HeadView的高度.並且在使用者手鬆開的時候,將ListView回滾到頂部,headView隱藏.
具體實現步驟:
1.在ListView的頂部增加一個headView,將headView的初始位置隱藏在ListView的上方.(即:在ListView裡面addHeaderView);
注:這一步的實現,需要在ListView裡面測繪headView的高寬,方可顯示出來.有點類似繼承View裡面的onmeasure()方法,不過因為是重寫ListView,這裡也要去measure,HeadView的高寬;具體程式碼如下:

private void measureView(View headview) {
        //設定LayoutParams來設定width和height;
        ViewGroup.LayoutParams p = headview.getLayoutParams();
        if (p == null){
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        //這邊寬度就是p的寬度,也就是父容器的width,listView是限制寬度的,所以需要getChildMeasureSpec這個方法
int childWidthSpec = ViewGroup.getChildMeasureSpec(0,0,p.width); //接下來是高度 int lpheight = p.height; int childHeightSpec; if (lpheight > 0){ //通過makeMeasureSpec方法來獲取高度 childHeightSpec = MeasureSpec.makeMeasureSpec(lpheight,MeasureSpec.EXACTLY);//精確模式 }else{ childHeightSpec = MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED);//不指定大小 } //寬高賦值給headview headview.measure(childWidthSpec, childHeightSpec); }

2.新增進去之後,那就是最初的顯示,把headview隱藏到listview上,檢視不可見;

    addHeaderView(headview);//新增到父佈局的headView
        headviewHeight = headview.getMeasuredHeight();//獲取到測量的高度
        headview.setPadding(0,-headviewHeight,0,0);//隱藏到上面

3.在listview處於頂部的時候,監聽使用者滑動的過程監聽使用者手勢進行下拉,否則,就不能下拉,那麼就會用到AbsListView.OnScrollListener這個監聽,噹噹前可見item的postion=0的時候,才下拉:

 @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {

    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        //在移動的過程中,把可見的第一項賦值給全域性變數,方便後面下拉重新整理
        mFirstVisibleItem = firstVisibleItem;
    }

4.就是我們的下拉回滾,主要是重寫當前listview的ontouch事件來具體實現.ACTION_MOVE的程式碼主要是來實現listview隨手勢下拉,headview高度增加;ACTION_UP的程式碼主要是listview回滾的彈性特效,其實也監簡單就一句程式碼就搞定,主要用了這個smoothScrollBy()方法,程式碼:

//重寫onTouch方法,實現listview下拉回滾特效
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                //如果當前listview處於初始狀態,也就是第一個可見item的postion為0的時候,記錄手指滑動的Y軸座標
                if (mFirstVisibleItem == 0){
                    startY = ev.getY();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float tempY = ev.getY();
                //在頂部時,給偏移量賦值
                if (mFirstVisibleItem == 0){
//                    startY = tempY;
                    offsetY = tempY - startY;
                    float currentHeight = (-headviewHeight+offsetY/3);
                    headview.setPadding(0, (int) currentHeight, 0, 0);//這一步就是實現listView隨手勢下拉,headview高度增加
                }
                break;
            case MotionEvent.ACTION_UP:
//                this.smoothScrollBy((int)(-headviewHeight+offsetY/3)+headviewHeight, 500);
                //恢復到headView隱藏的高度
                this.smoothScrollBy(-headviewHeight, 500);
                headview.setPadding(0,-headviewHeight,0,0);//headview隱藏到上面
                break;
        }
        return super.onTouchEvent(ev);
    }

demo下載

http://download.csdn.net/detail/qq_28690547/9398483
注:demo是android-studio專案,如果還在用eclipse的同學,直接把res和java目錄檔案拷過去就能跑了哈,不過建議大家還是多用android-studio,真的很方便.

結語

整個過程就完整實現了,是不是很簡單了.其實自定義View我總結的,就跟咱們以前美術課拿筆在紙上作畫一樣,首先要明確想要畫什麼,其次你就會思考為了實現這個目標,我們第一步第二步第三步要做些什麼.最後就是具體實現這些步驟,與畫畫不一樣,咱們就是用程式碼來實現它而已.不過你這樣理解了,以後就對自定義控制元件不那麼恐懼了.

補充

其實一個很簡單的方法,也可以實現ListView的彈性效果,重寫ListView裡面的overScrollBy的方法,設定maxOverScrollY的值也可以簡單實現效果,(不過下拉重新整理涉及不同狀態改變其中的值,還是得用headview),程式碼:

/**
 * 重寫overScrollBy方法裡面的maxOverScrollY實現ListView的彈性效果
 * Created by max on 2016/1/10.
 */
public class DouListView extends ListView{

    public DouListView(Context context) {
        super(context);
    }

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

    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, 300, isTouchEvent);//這個300可以根據螢幕density來滿足多分佈需求.
    }
}

相關推薦

新手定義控制元件,建立屬於自己重新整理()---Android,ListView實現IOS彈性效果

前言 相信很多童鞋對於控制元件的下拉重新整理都比較熟悉吧,常用的PullToRefresh開源庫和Google自帶的SwipeRefreshLayout大家肯定也很熟悉吧,但作為一個Android開發新手,對於自定義控制元件和自定義View來實現一些效果肯定還

定義控制元件之:treelistCombox 樹列表

先來一張效果圖 下面是treelistcombox原始碼 using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; us

[WPF 定義控制元件]建立包含CheckBox的ListBoxItem

1. 前言 Xceed wpftoolkit提供了一個CheckListBox,效果如下: 不過它用起來不怎麼樣,與其這樣還不如參考UWP的ListView實現,而且動畫效果也很好看: 它的樣式如下: <ListViewItemPresenter ContentTransitions="

Android定義控制元件-Path之貝賽爾曲線和手勢軌跡、水波紋效果

從這篇開始,我將延續androidGraphics系列文章把圖片相關的知識給大家講完,這一篇先稍微進階一下,給大家把《android Graphics(二):路徑及文字》略去的quadTo(二階貝塞爾)函式,給大家補充一下。 本篇最終將以兩個例子給大家演示貝塞爾曲線

定義控制元件三部曲之動畫篇(十)——聯合動畫的XML實現與使用示例

前言:不畏人生,或許才能方得始終;大膽拼,大膽闖是要有一定資本的,在能力不到的時候,就只有選擇忍氣吞聲! 上篇給大家講了有關AnimatorSet的程式碼實現方法,這篇我們就分別來看看如何利用xml來實現ValueAnimator、ObjectAn

定義View——仿騰訊TIM重新整理View

一 概述 自定義 View 是 Android 開發裡面的一個大學問。偶然間看到 TIM 郵箱介面的重新整理 View 還挺好玩的,於是就自己動手實現了一個,先看看 TIM 裡邊的效果圖: 二 需求分析 看到上面的動圖,大概也知道我們需要實現的功能: 根據拖動的進度來移動小球的位

duilib建立定義控制元件

我之前也寫過一片封裝xml為一個容器的文章,只是寫的很隨意,僅僅貼出了一個demo的地址。 在群裡還有一些剛剛接觸duilib的朋友們問到duilib自定義控制元件的問題,這裡我轉載一篇redrain大佬的博文。主要是這篇文章寫的太好了,我們直接參考理解就好,我寫的肯定沒這個好。原文地址:htt

定義控制元件不能在winform程式碼中建立

怎麼用程式碼清空除錯的時候輸出裡面的內容Asp.NetCore貌似不能執行在樹莓派上面問了很多人說.NetCore有ARM版本我倒是沒找到怎麼用程式碼清空除錯的時候輸出裡面的內容Asp.NetCore貌似不能執行在樹莓派上面問了很多人說.NetCore有ARM版本我倒是沒找到

第一行程式碼 3.4.2 建立定義控制元件 章節中初上手出項的下載完成後閃退問題和定義控制元件無反應問題

關於出項下載後閃退並且開啟app時也閃退的問題,主要是xml檔案出錯,一般情況按照書中的流程title.xml檔案是沒有錯誤的,主要原因在於 activity_main.xm了檔案中,直接說程式碼 <RelativeLayout xmlns:android="http://schema

Labview-建立定義控制元件

labview中的控制元件種類很多,但是樣式或者外觀有時不能滿足我們的需求。如何製作一個好看酷酷的自定義控制元件呢? 以開關為例,我們先新增一個labview中自帶的確定開關控制元件   之後右鍵該控制元件--高階--自定義    

第一行程式碼 3.4.2 建立定義控制元件 章節中初上手出項的下載完成後閃退問題和定義控制元件無反應問題

關於出項下載後閃退並且開啟app時也閃退的問題,主要是xml檔案出錯,一般情況按照書中的流程title.xml檔案是沒有錯誤的,主要原因在於 activity_main.xm了檔案中,直接說程式碼 <RelativeLayout xmlns:android="http

Qt定義控制元件建立與初步使用(二)之圖片上繪製文字、箭頭、曲線

本文目的:編輯自定義控制元件的介面ui,並在圖片上添文字、箭頭、曲線、開啟、儲存等功能。並說明了如何去使用這個編輯好的ui介面控制元件! 上次簡單的說明了如何去建立Qt自定義控制元件,當時還是對其瞭解不夠深刻,現在看來,QT自定義控制元件就是你事先把介面寫好(一般基於QWi

Qt定義控制元件建立與初步使用

本篇部落格的目的是簡單介紹:建立一個用QLabel類來顯示圖片的自定義控制元件的編寫。在寫自定義控制元件的過程中遇到了很多的難題,但都慢慢解決了,本人對Qt自定義控制元件的認識還不深刻,做的不對的地方,還請大家指出,我會盡快修改,免得誤導他人! 配置:Qt creator5

Android定義控制元件:將ViewPager封裝自己的TabPager控制元件

用途 最近專案頁面中經常出現諸如下圖的控制元件,如果為每個頁面分別寫一個將會造成非常多的重複程式碼,不利於專案的閱讀和維護,也會使專案變得非常凌亂。所以,對於這種情況我們可以進行一定的抽取,傳入相關資料後自動顯示到控制元件上。

【轉】C#定義控制元件:WinForm將其它應用程式窗體嵌入自己內部

PS:文末的附件已更新,這次我放到部落格園裡面了,不會彈出廣告,放心下載,O(∩_∩)O謝謝! 這是最近在做的一個專案中提到的需求,把一個現有的窗體應用程式介面嵌入到自己開發的窗體中來,看起來就像自己開發的一樣(實際上……跟自己開發的還是有一點點區別的,就是內嵌程式和宿

編寫Qt Designer定義控制元件)——如何建立並使用Qt定義控制元件

    http://blog.csdn.net/giselite/article/details/12622429   在使用Qt Designer設計窗體介面時,我們可以使用Widget Box裡的窗體控制元件非常方便的繪製介面,比如拖進去一個按鈕,一個文字編輯器等。雖然Qt Designer裡的控制元

WPF/Blend4之定義控制元件——製作自己的Button

先展示一下效果圖 先用Ellipse控制元件畫一個30*30的橢圓,找到畫筆屬性Fill,選擇下面的漸變畫筆,左下角選擇徑向漸變,起始顏色設成#FFFF0000,結束顏色設成#FFFFC8C8 右鍵點Ellipse選擇構成控制元件 選擇Button,確定,進入Butt

iOS - 建立可以在 InterfaceBuilder 中實時預覽的定義控制元件

一、需求實現一個前後帶圖示的輸入框 這是一個簡單的自定義控制元件,很容易想到自定義一個檢視(UIView),然後前後的圖示使用 UIImageView 或者 UIButton 顯示,中間放一個 UITextField 就可以了 實現方式上可以 InterfaceBuilder 建立,也可以使用純程式

iOS定義控制元件-UISearchBar

   在開發過程中,UISearchBar屬不多見的控制元件,在我們一般使用的是系統原生樣式:    但是UI設計師可能想要的是這種:    可能你覺得很簡單:覺得設定背景顏色,邊框圖示什麼的;

定義控制元件之側滑關閉 Activity 控制元件

隔壁 iOS 的小夥伴有一個功能就是左手向右手一個慢動作,輕輕一劃就可以關閉介面,這種操作感覺還是很絲滑的,而且這還是 iOS 系統自帶的功能,由於 Android 手機早期是有 back 鍵,home 鍵 和選單鍵(現在大部分手機都只保留一個鍵了),所以 Android 是沒有這個功能的。現在