android listview item點擊展開,androidlistview

來源:互聯網
上載者:User

android listview item點擊展開,androidlistview

最近做項目真是頭疼呢?之前想用ListViewAnnotation來著,就是可以實作類別似於android 通知欄滑動刪除的效果。好像是一位大牛自己一個人寫的吧。我在這裡首先向他致敬。不過,話說回來,實現原理也是比較易於理解的,就是檢測你的滑動距離以及速度,再作出判斷,進行操作。具體大家參考下Google keep的兩種列表模式下滑動刪除的操作就理解類。

非常不幸的事,我再布局中用了fragment和biewpager,所以產生了手勢衝突,我為此改寫了library裡的手勢操作檢測方法,最後勉強改出來的。但是!!!!效果實在慘不忍睹,只好作罷,最後,思來想去,我決定使用listview item點擊展開來實現我想要的效果。

好吧,廢話說了很多,終於要進入正題了。
首先補充三點知識:

第一點:

getLayoutParams()方法和setLayoutParams()用法首先,我們利用getLayoutParams()來獲得指定控制項的LayoutParams。例如:LinearLayout.LayoutParams lp = (RelativeLayout.LayoutParams) deletButton.getLayoutParams();然後,我們可以為deleteButton設定layoutparams屬性,例如:    lp.width = btnWidth;    lp.leftMargin = 10;最後,我們將設定好的layoutparams屬性設定給指定的控制項:        deletButton.setLayoutParams(lp);

第二點:

public final int getMeasuredHeight ()Added in API level 1Like getMeasuredHeightAndState(), but only returns the raw width component (that is the result is masked by MEASURED_SIZE_MASK).ReturnsThe raw measured height of this view.public final int getHeight ()Added in API level 1Return the height of your view.ReturnsThe height of your view, in pixels.getMeasuredHeight()返回的是原始測量高度,與螢幕無關,getHeight()返回的是在螢幕上顯示的高度。實際上在當螢幕可以包裹內容的時候,他們的值是相等的,只有當view超出螢幕後,才能看出他們的區別。當超出螢幕後,getMeasuredHeight()等於getHeight()加上螢幕之外沒有顯示的高度。

第三點:

MeasureSpec的使用。MeasureSpec一般出現在自訂View中,因為在自訂 view中我們經常需要重寫該方法,由它來指定自訂控制項在螢幕上的大小。protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)onMeasure傳入的兩個參數是由上一層控制項傳入的大小,有多種情況,重寫該方法時需要對計算控制項的實際大小,然後調用setMeasuredDimension(int, int)設定實際大小。onMeasure傳入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸數值,而是將模式和尺寸組合在一起的數值。我們需要通過int mode = MeasureSpec.getMode(widthMeasureSpec)得到模式,用int size = MeasureSpec.getSize(widthMeasureSpec)得到尺寸。mode共有三種情況,取值分別為MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。MeasureSpec.EXACTLY是精確尺寸,當我們將控制項的layout_width或layout_height指定為具體數值時如andorid:layout_width="50dip",或者為FILL_PARENT是,都是控制項大小已經確定的情況,都是精確尺寸。MeasureSpec.AT_MOST是最大尺寸,當控制項的layout_width或layout_height指定為WRAP_CONTENT時,控制項大小一般隨著控制項的子空間或內容進行變化,此時控制項尺寸只要不超過父控制項允許的最大尺寸即可。因此,此時的mode是AT_MOST,size給出了父控制項允許的最大尺寸。MeasureSpec.UNSPECIFIED是未指定尺寸,這種情況不多,一般都是父控制項是AdapterView,通過measure方法傳入的模式。然後,我們可以調用MeasureSpec.makeMeasureSpec(int size, int mode)來進行設定。

好,現在先上一張demo,使用者可以自己進行擴充。

哈哈,效果還行吧。那個,表徵圖略顯呆萌,還請不要見笑(自己繪製的,苦逼程式員一隻啊)。

好,接下來,我們來看一下動效的實現。當然,先上源碼。

package wenyue.expandlistview.me;import android.util.Log;import android.view.View;import android.view.animation.Animation;import android.view.animation.Transformation;import android.widget.LinearLayout.LayoutParams;    /**     * animation     * 2014年十一月十八日     * 蒼狼問月     * canglangwenyue.github.io     * @author canglangwenyue     *     */public class ViewExpandAnimation extends Animation {private View mAnimationView = null;private LayoutParams mViewLayoutParams = null;private int mStart = 0;private int mEnd = 0;public ViewExpandAnimation(View view){    animationSettings(view, 500);}public ViewExpandAnimation(View view, int duration){    animationSettings(view, duration);}private void animationSettings(View view, int duration){    setDuration(duration);    mAnimationView = view;    mViewLayoutParams = (LayoutParams) view.getLayoutParams();    mStart = mViewLayoutParams.bottomMargin;    mEnd = (mStart == 0 ? (0 - view.getHeight()) : 0);    view.setVisibility(View.VISIBLE);}@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) {    super.applyTransformation(interpolatedTime, t);    if(interpolatedTime < 1.0f){        mViewLayoutParams.bottomMargin = mStart + (int) ((mEnd - mStart) * interpolatedTime);        // invalidate        mAnimationView.requestLayout();    }else{        mViewLayoutParams.bottomMargin = mEnd;        mAnimationView.requestLayout();        if(mEnd != 0){            mAnimationView.setVisibility(View.GONE);        }    }    Log.i("hehe", "interpolatedTime = " + interpolatedTime + " , bottomMargin" +             mViewLayoutParams.bottomMargin);}}動效實現的代碼不多,setDuration(duration)設定動效的期間。之後調用RelitaveLayout.bottomMargin;對於該屬性developer文檔解釋為The bottom margin in pixels of the child.mAnimationView.requestLayout();該方法內部會調用Object.layout(...)方法,來重會布局。

至於,listview adapter的重寫,就比較簡單了。所以,不再貼出全部源碼。只說一下需要注意的地方。
首先,你需要在getView(…)中載入自訂listview 的item布局檔案:

convertView = myInflater.inflate(R.layout.expand_item, null);

接下來,貼出相應布局檔案代碼:

<?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"android:padding="5dip" ><RelativeLayout    android:id="@+id/header"    android:layout_width="match_parent"    android:layout_height="wrap_content" >    <LinearLayout        android:id="@+id/appInfo"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginLeft="5dip"        android:orientation="vertical" >        <TextView            android:id="@+id/tvName"            android:layout_width="match_parent"            android:layout_height="45dp"            android:gravity="center|left"            android:text="name"            android:textColor="#000000"            android:layout_marginLeft="20.0dip"            android:textSize="16sp" />    </LinearLayout></RelativeLayout><RelativeLayout    android:id="@+id/footer"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:background="#ffffff" >    <Button        android:id="@+id/btnOpen"        android:layout_width="100dip"        android:layout_height="wrap_content"        android:layout_alignParentLeft="true"        android:layout_marginTop="6dip"        android:focusable="false"        android:textColor="#000000"        android:background="@drawable/editbutton"        android:textSize="16sp" />    <Button        android:id="@+id/btnView"        android:layout_width="100dip"        android:layout_height="wrap_content"        android:layout_marginTop="6dip"        android:layout_toRightOf="@id/btnOpen"        android:focusable="false"        android:background="@drawable/start"        android:textColor="#000000"        android:textSize="16sp" />    <Button        android:id="@+id/btnWarning"        android:layout_width="100dip"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:layout_marginTop="6dip"        android:focusable="false"        android:background="@drawable/tomatodeletebutton"        android:textColor="#000000"        android:textSize="16sp" /></RelativeLayout></LinearLayout>

我設定的是預設在activity onStart時嵌套布局中的第二個RelativeLayout布局檔案的內容是被隱藏的。
在BaseAdapter中的設定如下:

RelativeLayout footer = (RelativeLayout) convertView                .findViewById(R.id.footer);        int widthSpec = MeasureSpec.makeMeasureSpec(                (int) (mLcdWidth - 10 * mDensity), MeasureSpec.EXACTLY);        footer.measure(widthSpec, 0);        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) footer                .getLayoutParams();        params.bottomMargin = -footer.getMeasuredHeight();        footer.setVisibility(View.GONE);

然後,是在onCreate方法中設定setOnItemClickListener方法,在其中設定點擊item後,開始動效,再次點擊則隱藏,且同一時間只有一個item可以展開(因為個人認為使用者不可能在同一時間操作兩個 item的隱藏操作),代碼如下:

if (mLastTouchTag != null) {                View temp = arg0.findViewWithTag(mLastTouchTag);                if (temp != null) {                    View footTemp = temp.findViewById(R.id.footer);                    if (footTemp != null                            && (footTemp.getVisibility() != View.GONE)) {                        footTemp.startAnimation(new ViewExpandAnimation(                                footTemp));                    }                }            }            mLastTouchTag = (ViewHolder) v.getTag();            // onion555 end            View footer = v.findViewById(R.id.footer);            footer.startAnimation(new ViewExpandAnimation(footer));

好吧,就寫到這裡吧,有什麼問題,請留言。同樣,在最後附上源碼。
點擊開啟連結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.