㈠ android 下拉滾動頁面怎麼實現
以下是我自己花功夫編寫了一種非常簡單的下拉刷新實現方案,現在拿出來和大家分享一下。相信在閱讀完本篇文章之後,大家都可以在自己的項目中一分鍾引入下拉刷新功能 最近項目中需要用到ListView下拉刷新的功能,一開始想圖省事,在網上直接找一個現成的,可是嘗試了網上多個版本的下拉刷新之後發現效果都不 怎麼理想。有些是因為功能不完整或有Bug,有些是因為使用起來太復雜,十全十美的還真沒找到。因此我也是放棄了在網上找現成代碼的想法,自己花功夫編寫 了一種非常簡單的下拉刷新實現方案,現在拿出來和大家分享一下。相信在閱讀完本篇文章之後,大家都可以在自己的項目中一分鍾引入下拉刷新功能。 首先講一下實現原理。這里我們將採取的方案是使用組合View的方式,先自定義一個布局繼承自LinearLayout,然後在這個布局中加入下拉 頭和ListView這兩個子元素,並讓這兩個子元素縱向排列。初始化的時候,讓下拉頭向上偏移出屏幕,這樣我們看到的就只有ListView了。然後對 ListView的touch事件進行監聽,如果當前ListView已經滾動到頂部並且手指還在向下拉的話,那就將下拉頭顯示出來,鬆手後進行刷新操 作,並將下拉頭隱藏。原理示意圖如下: 那我們現在就來動手實現一下,新建一個項目起名叫PullToRefreshTest,先在項目中定義一個下拉頭的布局文件pull_to_refresh/apk/res/android" xmlns:tools="schemas/tools" android:id="@+id/pull_to_refresh_head" android:layout_width="fill_parent" android:layout_height="60dip" > <LinearLayout android:layout_width="200dip" android:layout_height="60dip" android:layout_centerInParent="true" android:orientation="horizontal" > <RelativeLayout android:layout_width="0dip" android:layout_height="60dip" android:layout_weight="3" > <ImageView android:id="@+id/arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@drawable/arrow" /> <ProgressBar android:id="@+id/progress_bar" android:layout_width="30dip" android:layout_height="30dip" android:layout_centerInParent="true" android:visibility="gone" /> </RelativeLayout> <LinearLayout android:layout_width="0dip" android:layout_height="60dip" android:layout_weight="12" android:orientation="vertical" > <TextView android:id="@+id/description" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:gravity="center_horizontalbottom" android:text="@string/pull_to_refresh" /> <TextView android:id="@+id/updated_at" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:gravity="center_horizontaltop" android:text="@string/updated_at" /> </LinearLayout> </LinearLayout> </RelativeLayout> 在這個布局中,我們包含了一個下拉指示箭頭,一個下拉狀態文字提示,和一個上次更新的時間。當然,還有一個隱藏的旋轉進度條,只有正在刷新的時候我們才會將它顯示出來。 布局中所有引用的字元串我們都放在stringsmit(); new HideHeaderTask()/apk/res/android" xmlns:tools="schemas/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <com.example.pulltorefreshtest.RefreshableView android:id="@+id/refreshable_view" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ListView android:id="@+id/list_view" android:layout_width="fill_parent" android:layout_height="fill_parent" > </ListView> </com.example.pulltorefreshtest.RefreshableView> </RelativeLayout> 可以看到,我們在自定義的RefreshableView中加入了一個ListView,這就意味著給這個ListView加入了下拉刷新的功能,就是這么簡單! 然後我們再來看一下程序的主Activity,打開或新建MainActivity,加入如下代碼: 復制代碼 代碼如下: public class MainActivity extends Activity { RefreshableView refreshableView; ListView listView; ArrayAdapter<String> adapter; String[] items = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); refreshableView = (RefreshableView) findViewById(R.id.refreshable_view); listView = (ListView) findViewById(R.id.list_view); adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items); listView.setAdapter(adapter); refreshableView.setOnRefreshListener(new PullToRefreshListener() { @Override public void onRefresh() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } refreshableView.finishRefreshing(); } }, 0); } } 可 以看到,我們通過調用RefreshableView的setOnRefreshListener方法注冊了一個監聽器,當ListView正在刷新時就 會回調監聽器的onRefresh方法,刷新的具體邏輯就在這里處理。而且這個方法已經自動開啟了線程,可以直接在onRefresh方法中進行耗時操 作,比如向伺服器請求最新數據等,在這里我就簡單讓線程睡眠3秒鍾。另外在onRefresh方法的最後,一定要調用RefreshableView中的 finishRefreshing方法,這個方法是用來通知RefreshableView刷新結束了,不然我們的ListView將一直處於正在刷新的 狀態。 不知道大家有沒有注意到,setOnRefreshListener這個方法其實是有兩個參數的,我們剛剛也是傳入了一個不起眼的 0。那這第二個參數是用來做什麼的呢?由於RefreshableView比較智能,它會自動幫我們記錄上次刷新完成的時間,然後下拉的時候會在下拉頭中 顯示距上次刷新已過了多久。這是一個非常好用的功能,讓我們不用再自己手動去記錄和計算時間了,但是卻存在一個問題。如果當前我們的項目中有三個地方都使 用到了下拉刷新的功能,現在在一處進行了刷新,其它兩處的時間也都會跟著改變!因為刷新完成的時間是記錄在配置文件中的,由於在一處刷新更改了配置文件, 導致在其它兩處讀取到的配置文件時間已經是更改過的了。那解決方案是什麼?就是每個用到下拉刷新的地方,給setOnRefreshListener方法 的第二個參數中傳入不同的id就行了。這樣各處的上次刷新完成時間都是單獨記錄的,相互之間就不會再有影響。 好了,全部的代碼都在這里了,讓我們來運行一下,看看效果吧。 效果看起來還是非常不錯的。我們最後再來總結一下,在項目中引入ListView下拉刷新功能只需三步: 1. 在Activity的布局文件中加入自定義的RefreshableView,並讓ListView包含在其中。 2. 在Activity中調用RefreshableView的setOnRefreshListener方法注冊回調介面。 3. 在onRefresh方法的最後,記得調用RefreshableView的finishRefreshing方法,通知刷新結束。 從此以後,在項目的任何地方,一分鍾引入下拉刷新功能妥妥的。 好了,今天的講解到此結束,有疑問的朋友請在下面留言。 源碼下載,請點擊這里
㈡ 怎樣在Android Menu item中使用自定義View
1.自定義屬性:attrs.xml
2.MenuItemView.java源碼:
package com.dandy.widget;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.StateListDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import com.lingyun.switchbutton.R;
/**
* 設置,菜單中的布局項
* 默認控制項是縱向居中顯示,所有paddingTop和paddingBottom在這沒有作用
* Created by dandy on 2016/4/14.
*/
public class MenuItemView extends View{
private static final String TAG = "MenuItemView";
/**默認是按下狀態的最小值**/
private static final long PRESSED_TIMEOUT = 10;
/**默認控制項距離邊界的大小**/
private static final int PADDING_DEFAULT = 18;
/**默認控制項的高**/
private static final int HEIGHT_DEFAULT = 50;
/**文字繪制時默認大小**/
private static final int TEXTSZIE_DEFAULT = 14;
/**尾部箭頭圖標大小**/
private static final int ARROW_SIZE = 13;
/***SwitchButton默認寬*/
private static final int SWITCHBUTTON_WIDTH = 50;
/***SwitchButton默認高*/
private static final int SWITCHBUTTON_HEIGHT = 28;
/**頭標**/
private Drawable headerDrawable;
/**頭標寬**/
private int headerDrawableWidth;
/**頭標高**/
private int headerDrawableHeight;
/**距離左邊緣的距離**/
private int paddingLeft;
/**距離右邊緣的距離**/
private int paddingRight;
/**繪制頭標時,畫布在Y軸的繪制偏移量**/
private float headerDrawableStartDrawY;
/**文字與圖片間的距離**/
private int drawablePadding = -1;
/**頭部文字提示**/
private String textHeader;
/**文字顏色**/
private int textHeaderColor = Color.parseColor("#5a5a5a");
/**文字大小**/
private int textSize = -1;
/**文字繪制時,畫布在Y軸的繪制偏移量**/
private float textStartDrawY;
/**繪制文字的畫筆**/
private Paint textPaint;
/** 尾部 > 圖片**/
private Drawable arrowDrawable;
/**尾部 > 大小**/
private int arrowSize = -1;
/** > 繪制的X軸偏移量**/
private float arrowStartDrawX;
/** > 繪制的Y軸偏移量**/
private float arrowStartDrawY;
/**footerDrawable != null 時,繪制的時候是否按照原圖片大小繪制**/
private boolean arrowWropToSelf = true;
/**尾部寬**/
private int arrowDrawableWidth;
/**尾部高**/
private int arrowDrawableHeight;
/**繪制arrow畫筆**/
private Paint arrowPaint;
/**arrowPaint 顏色**/
private int arrowColor = Color.parseColor("#5a5a5a");
private DisplayMetrics dm;
/*以下是繪制SwitchButton所用到的參數*/
private Style style = Style.CUSTOM_ITEM;
/**默認寬**/
private int switchButtonWidth = -1;
/**默認高**/
private int switchButtonHeight = -1;
private static final long DELAYDURATION = 10;
/**開啟顏色**/
private int onColor = Color.parseColor("#4ebb7f");
/**關閉顏色**/
private int offColor = Color.parseColor("#dadbda");
/**灰色帶顏色**/
private int areaColor = Color.parseColor("#dadbda");
/**手柄顏色**/
private int handlerColor = Color.parseColor("#ffffff");
/**邊框顏色**/
private int borderColor = offColor;
/**開關狀態**/
private boolean toggleOn = false;
/**邊框寬**/
private int borderWidth = 2;
/**縱軸中心**/
private float centerY;
/**按鈕水平方向開始、結束的位置**/
private float startX,endX;
/**手柄x軸方向最小、最大值**/
private float handlerMinX,handlerMaxX;
/**手柄大小**/
private int handlerSize;
/**手柄在x軸的坐標位置**/
private float handlerX;
/**關閉時內部灰色帶寬度**/
private float areaWidth;
/**是否使用動畫效果**/
private boolean animate = true;
/**是否默認處於打開狀態**/
private boolean defaultOn = true;
/**按鈕半徑**/
private float radius;
/**整個switchButton的區域**/
private RectF switchRectF = new RectF();
/**繪制switchButton的畫筆**/
private Paint switchPaint;
private OnToggleChangedListener mListener;
private Handler mHandler = new Handler();
private double currentDelay;
private float downX = 0;
/**switchButton在X軸繪制的偏移量**/
private float switchButtonDrawStartX;
/**switchButton在Y軸繪制的偏移量**/
private float switchButtonDrawStartY;
/**分割線,默認在底部繪制**/
private Drawable dividerr;
/**分割線繪制的寬**/
private int dividerWidth = 2;
/**是否需要繪制分割線**/
private boolean dividerVisibilty = true;
/**觸摸事件是否完成**/
private boolean touchDownEnd = false;
public MenuItemView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setup(attrs);
}
public MenuItemView(Context context, AttributeSet attrs) {
super(context, attrs);
setup(attrs);
}
/**
* 初始化控制項,獲取相關的控制項屬性
* @param attrs
*/
private void setup(AttributeSet attrs){
dm = Resources.getSystem().getDisplayMetrics();
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.MenuItemView);
if(typedArray != null){
int count = typedArray.getIndexCount();
for(int i = 0;i < count;i++){
int attr = typedArray.getIndex(i);
switch (attr){
case R.styleable.MenuItemView_headerDrawable:
headerDrawable = typedArray.getDrawable(attr);
break;
case R.styleable.MenuItemView_drawPadding:
drawablePadding = typedArray.getDimensionPixelSize(attr,drawablePadding);
break;
case R.styleable.MenuItemView_textHeader:
textHeader = typedArray.getString(attr);
break;
case R.styleable.MenuItemView_textHeaderColor:
textHeaderColor = typedArray.getColor(attr, textHeaderColor);
break;
case R.styleable.MenuItemView_textSize:
textSize = typedArray.getDimensionPixelSize(attr, textSize);
break;
case R.styleable.MenuItemView_arrowDrawable:
arrowDrawable = typedArray.getDrawable(attr);
break;
case R.styleable.MenuItemView_arrowSize:
arrowSize = typedArray.getDimensionPixelSize(attr, arrowSize);
break;
case R.styleable.MenuItemView_arrowWropToSelf:
arrowWropToSelf = typedArray.getBoolean(attr, true);
break;
case R.styleable.MenuItemView_arrowColor:
arrowColor = typedArray.getColor(attr, arrowColor);
break;
case R.styleable.MenuItemView_onColor:
onColor = typedArray.getColor(attr, onColor);
break;
case R.styleable.MenuItemView_offColor:
borderColor = offColor = typedArray.getColor(attr,offColor);
break;
case R.styleable.MenuItemView_areaColor:
areaColor = typedArray.getColor(attr, areaColor);
break;
case R.styleable.MenuItemView_handlerColor:
handlerColor = typedArray.getColor(attr, handlerColor);
break;
case R.styleable.MenuItemView_bordeWidth:
borderWidth = typedArray.getColor(attr, borderWidth);
break;
case R.styleable.MenuItemView_animate:
animate = typedArray.getBoolean(attr, animate);
break;
case R.styleable.MenuItemView_defaultOn:
defaultOn = typedArray.getBoolean(attr, defaultOn);
break;
case R.styleable.MenuItemView_Style:
style = Style.getValue(typedArray.getInt(attr, Style.CUSTOM_ITEM.ordinal()));
break;
case R.styleable.MenuItemView_switchButtonWidth:
switchButtonWidth = typedArray.getDimensionPixelOffset(attr, switchButtonWidth);
break;
case R.styleable.MenuItemView_switchButtonHeight:
switchButtonHeight = typedArray.getDimensionPixelOffset(attr, switchButtonHeight);
break;
case R.styleable.MenuItemView_dividerr:
dividerr = typedArray.getDrawable(attr);
break;
case R.styleable.MenuItemView_dividerWidth:
dividerWidth = typedArray.getDimensionPixelOffset(attr,dividerWidth);
break;
case R.styleable.MenuItemView_dividerVisibilty:
dividerVisibilty = typedArray.getBoolean(attr,dividerVisibilty);
break;
}
}
typedArray.recycle();
}
㈢ android有帶箭頭的按鈕控制項嗎
沒有自帶箭頭的按鈕,都是依靠圖片。可以做一個箭頭圖片,然後按鈕背景設置為這個圖片就行了。
步驟:
1、在drawable下放入箭頭圖片arrow.png(http://www.jitu5.com/vector/201403/362739.html)
2、按鈕設置android:background="@drawable/arrow"
㈣ Android編程問題之R.drawable.icon
Android 自帶圖標庫 android.R.drawable
desandroidstylejavahtmlsrc文件Gocom
在xml文件中調用。
android:title="@string/secure_connect"
android:orderInCategory="100"
android:icon="@android:drawable/ic_menu_search"
android:drawableRight="@android:drawable/arrow_down_float"/>
程序中調用。
setIcon(android.R.drawable.stat_notify_error)
Android 自帶圖標庫 android.R.drawable