編輯:關於Android編程
package com.example.zq.pullfresh;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by zq on 2016/4/26.
*/
public class MyListView extends ListView {
private final View viewHeader;
private static final byte DONE = 1;
private static final byte PULL = 2;
private static final byte RELEASE = 3;
private static final byte RELEASE_NOT_FRESHING = 4;
private byte currentState;
private final int height;
private TextView tvState, tvTime;
private ImageView ivArrow;
private ProgressBar pBar;
private int downY, moveY, showY;
private onRefreshingListener onRefreshingListener;
// TODO: 2016/4/26 構造方法
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO: 2016/4/26 構建下拉刷新的布局
viewHeader = View.inflate(context, R.layout.layout_header, null);
setViews(viewHeader);// TODO: 2016/4/26 控件初始化
this.addHeaderView(viewHeader);// TODO: 2016/4/26 添加頭部刷新布局
viewHeader.measure(0, 0);// TODO: 2016/4/26 精確測量
height = viewHeader.getMeasuredHeight();// TODO: 2016/4/26 獲取布局的高度
viewHeader.setPadding(0, -height, 0, 0);// TODO: 2016/4/26 隱藏刷新布局
String strCurrentDate = GetCurrentDate();
tvTime.setText(strCurrentDate);// TODO: 2016/4/26 設置系統當前時間
currentState = DONE;
}
private void setViews(View viewHeader) {
tvState = (TextView) viewHeader.findViewById(R.id.tv_state);// TODO: 2016/4/26 下拉狀態
tvTime = (TextView) viewHeader.findViewById(R.id.tv_updateTime);// TODO: 2016/4/26 刷新時間
ivArrow = (ImageView) viewHeader.findViewById(R.id.iv_arrow);// TODO: 2016/4/26 下拉時箭頭
pBar = (ProgressBar) viewHeader.findViewById(R.id.progressBar);// TODO: 2016/4/26 進度條
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:// TODO: 2016/4/26 手勢按下
if (currentState == DONE) {
currentState = PULL;
downY = (int) ev.getY();// TODO: 2016/4/26 獲取按下時的Y坐標
}
break;
case MotionEvent.ACTION_MOVE:// TODO: 2016/4/27 手勢移動
if (currentState == PULL) {
moveY = (int) ev.getY();// TODO: 2016/4/26 移動時的Y坐標
showY = moveY - downY + (-height);// TODO: 2016/4/26 獲取下拉顯示的長度
viewHeader.setPadding(0, showY, 0, 0);//// TODO: 2016/4/26 下拉的時候慢慢的將布局顯示出來
// TODO: 2016/4/26 判斷向下拉了很久
if (showY > height) {
ivArrow.setImageResource(R.mipmap.ic_launcher);// TODO: 2016/4/26 將下拉箭頭設置為上拉箭頭
tvState.setText("松開刷新");
currentState = RELEASE;
}
}
break;
case MotionEvent.ACTION_UP:// TODO: 2016/4/27 手勢抬起
// TODO: 2016/4/26 下拉了一段距離但是沒有刷新的情況
if (showY < height) {
ivArrow.setImageResource(R.drawable.arrow);// TODO: 2016/4/26 設置下拉箭頭
ivArrow.setVisibility(View.VISIBLE);// TODO: 2016/4/26 設置下拉箭頭可見
pBar.setVisibility(View.GONE);
tvState.setText("下拉刷新");
viewHeader.setPadding(0, -height, 0, 0);// TODO: 2016/4/26 隱藏下拉刷新布局
currentState = DONE;
}
if (currentState == RELEASE) {
tvState.setText("正在刷新");
pBar.setVisibility(View.VISIBLE);
ivArrow.setVisibility(View.GONE);
String strCurrentDate = GetCurrentDate();
tvTime.setText(strCurrentDate);// TODO: 2016/4/26 設置刷新時間,為系統當前時間
// TODO: 2016/4/26 比如聯網獲取數據,可以讓別人調接口
if (onRefreshingListener != null) {
// TODO: 2016/4/27 主界面回調該方法,但在主界面對該方法做具體的實現
this.onRefreshingListener.onRefreshing(this);
}
}
break;
}
return super.onTouchEvent(ev);
}
// TODO: 2016/4/26 獲取系統當前的日期 格式為:yyyy-MM-dd HH:mm:ss
private String GetCurrentDate() {
SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date currentData = new Date(System.currentTimeMillis());//// TODO: 2016/4/26 獲取系統當前時間
String strDate = format.format(currentData);// TODO: 2016/4/26 格式化系統當前時間
return strDate;// TODO: 2016/4/26 返回格式化後的日期
}
// TODO: 2016/4/26 接收接口實現類
public void setOnRefreshingListener(onRefreshingListener onRefreshingListener) {
this.onRefreshingListener = onRefreshingListener;
}
public void completeRefresh() {
ivArrow.setImageResource(R.drawable.arrow);
ivArrow.setVisibility(VISIBLE);
pBar.setVisibility(View.GONE);
tvState.setText("下拉刷新");
viewHeader.setPadding(0, -height, 0, 0);// TODO: 2016/4/26 隱藏下拉刷新布局
currentState = DONE;// TODO: 2016/4/26 用於重復刷新
}
}
代碼很簡單,就是自定義了一個view,MyListView繼承ListView,重寫構造方法。在構造方法中,構建下拉刷新的布局,在代碼中構建的布局為viewHeader,即下拉刷新的布局;下拉刷新的xml布局如下所示:
xml的代碼為:
<framelayout android:layout_alignparentleft="true" android:layout_centervertical="true" android:layout_height="wrap_content" android:layout_width="wrap_content">
</framelayout>
代碼很簡單,就是一個線性布局裡面放置兩個布局,兩個布局再分別放置一些控件。其中第一個布局用的是幀布局,裡面有一個下拉箭頭的圖片和一個進度條,此時需要將進度條隱藏,設置android:visibility=”gone”就可以了。第二個布局用的是一個線性布局,裡面有兩個TextView控件,一個是用於當前狀態提示顯示,另一個是用於最近更新提示顯示。在MyListView類的構造方法中將下拉刷新布局構建好了之後,進行控件的一些初始化操作,就可以將該布局添加到頭部了,this.addHeaderView(viewHeader);添加到頭部的時候需要精確的測量布局的高度。高度測量完成後,設置padding,可以隱藏下拉刷新的布局,viewHeader.setPadding(0,-height, 0, 0);這裡為什麼要將top參數設置為-height,因為設置在頭部需要將其隱藏。一些當前狀態提示和時間提示的賦值我就不多說了,大家都看的懂,只要給對應的控件設置你需要讓其顯示的內容就可以了。下面開始關鍵的代碼講解:在MyListView類中重寫了屏幕的觸摸事件,為什麼要重寫該方法,因為下拉刷新這個功能是對手勢做判斷,執行相應操作實現的。如圖方法:
即重寫public boolean onTouchEvent(MotionEvent ev) { ......
方法。
return super.onTouchEvent(ev); }
在該方法中,首先獲取手勢動作action,手勢動作有三個:手勢按下,手勢移動,手勢抬起。
當手勢按下的時候,currentState賦值為PULL,獲取按下時的Y坐標。currentState是用於在不同的手勢之間切換的一個參數標記。此時按下就執行以上操作就可以。 接下來需要下拉移動了,手勢動作也相應的變成了手勢移動。在手勢移動的時候,判斷currentState是否為PULL,為PULL的話,就獲取移動時的Y坐標,根據手勢按下時的Y坐標和移動時的Y坐標獲取下拉顯示的長度showY。獲取的代碼是:showY = moveY - downY + (-height);將下拉的布局慢慢顯示出來就設置padding的tZ喎?/kf/ware/vc/" target="_blank" class="keylink">vcM6qtbHHsLvxyKG1xM/CwK3P1Mq+tcSzpLbIoaPV4tH5xOPSxravtcTKsbryvs2/ydLUwv3C/bXEz9TKvrP2wLTBy6Gj1eLKsdTZxdC2z8rHt/HP8s/Cz8LArcHLuty+w6OsyOe5+8rHtcS7sKOsvs29q8/CwK28/c23aXZBcnJvd8no1sPOqsnPwK28/c23o6zTydPaw7vT0MnPwK28/c23tcTNvMas18rUtKOsztK+zdPDaWNfbGF1bmNoZXK0+szmwcuho7Wxx7DXtMysz9TKvszhyr50dlN0YXRlvs3J6NbDzqombGRxdW87y8m/qsui0MImcmRxdW87o6zX7rrzvatjdXJyZW50U3RhdGW4s9a1zqpSRUxFQVNFoaMgytbKxtLGtq++zb3hyvjBy6OstMvKscrWysbMp8bwtcS2r9f3vs3AtMHLo6zK1srGzKfG8LXEyrG68rfWwb3W1sfpv/aho7Xa0rvW1s/CwK3Su7bOvuDA67WrysfDu9PQy6LQwrXEx+m/9qO7we3Su9bWvs3Kx8rNt8XLotDCtcTH6b/2oaPPwsCt0ru2zr7gwOu1q8O709DLotDCtcTH6b/208PM9bz+JnJkcXVvO3Nob3dZICZsdDsgaGVnaHQmcmRxdW87wLTF0LbPo6zI57n7uMPM9bz+s8nBoqOsvs3LtcP3xOO0y8qxxOPPwru51NrPwsCto6zPwsCtw7vT0L3hyvijrLTLyrHLyb+qo6y8tMrWysbMp8bwtcTKsbryo6zPwsCty6LQwrK8vta+zbvh1NnSu7TOtcTS/rLYoaPT0MjLu+HOytXiwO/Oqsqyw7TTw3Nob3dZICZsdDsgMMC01/bF0LbPo7+1sbK8vta41brDyKuyv8/Uyr6z9sC0tcTKsbryvs3M4cq+xOO/ydLUy6LQwsHLsrvKx7j8usPC8KO/yOe5+8Tj1eLR+czhzsqjrLmnz7LE46OsztLOqsqyw7TV4tH50LTE49OmuMO2rsHLo6zO0ta7ysfIw8bkz8LArbXEvuDA69TZs6TSu7Xj1NnWtNDQy6LQwrLZ1/eho9a70qrKx7Tz09ow0tTJz7XEyv3Wtb7Nv8nS1KOsv7TE47j2yMu1xM+yusPBy6GjILb4ys23xcui0MK1xMfpv/bTw8z1vP5jdXJyZW50U3RhdGUgPT0gUkVMRUFTRcC0xdC2z6OstbG0y8z1vP6zycGio6y8tMrWysbSxravveHK+Lrzo6jK1srG0sa2r8qxz8LArcHL1+O5u7OktcS+4MDro6mjrLj4tbHHsNe0zKzP1Mq+zOHKvnR2U3RhdGXJ6NbDzqombGRxdW871f3U2sui0MImcmRxdW87o6y9+LbIzPXJ6NbDzqrP1Mq+o6zPwsCtvP3Nt8no1sPOqrK7v8m8+6GjtbHHsMui0MLKsbzkdHZUaW1lyejWw86qz7XNs7Wxx7DKsbzko6zV4rj2uty88rWlo6y0+sLr09DXosrNo6y087zS06a4w7a8xNy2rqGjvdPPwsC0vs3Kx7vxyKHK/b7dtcTKsbrywcujrMui0MLKx86qwcu4ycqyw7SjrMrHzqrBy7vxyKHSu9CpzfjC58nPtcTK/b7doaO52Lz8tcS12Le9wLTBy6Os1eLA78Tjv8nS1NC0uPa907/ao6zIw7HwyMu72LX3xOO907/atcS3vbeoo6zU2rHwyMvEx8DvttS4w7e9t6jX9r7fzOW1xMq1z9aho7j4tPO80su1vt/M5bXjsMmjob/JxNzT0LXEyMuyu8rHuty2rqGjILXa0ruyvaO6tLS9qNK7uPa907/ao6zI58/CzbzL+cq+o7ogPGltZyBhbHQ9"創建的接口" src="http://img.blog.csdn.net/20160427135313298" title="\" /> 第二步:在MyListView類寫一個方法用於接收接口實現類,方法名稱為:setOnRefreshingListener(onRefreshingListener onRefreshingListener)該方法用於接收一個接口參數,也就是剛剛定義的接口。如下圖所示: * 第三步:在釋放刷新,比如聯網獲取數據,可以讓別人調你的接口,如下圖所示: * 第四步:在MainActivity中用MyListView對象調用接收接口實現類方法,當調用該方法後需要執行接口中的onRefreshingListener.onRefreshing()方法,也就相當於在MainActivity中回調了第三步當中提到的方法this.RefreshingListener.onRefreshing(this)。但是具體的操作還是在MainActivity中實現。這其實也就是android中接口的回調機制,如果還不是很懂的就自己去百度“接口回調機制 ”,弄清楚它。 在MainActivity中具體的實現方式如下圖所示: 以上圖片中我標記了4處重要的地方,第一處是讓線程休眠1s,模擬獲取數據的操作;第二處是往集合中添加獲取的數據,我這裡也只用了簡單的添加方式;第三處是adapter更新數據源的變化,因為往集合中添加了數據,所以執行該方法可以更新adapter中內容。但是更新UI的操作需要執行在主線程,故runOnUiThread(…);第四處是執行方法myListView.completeRefresh();用於完成數據的刷新操作。此時又回到了MyListView這個類中,在該類中去實現該方法。主要是聯網完成了,隱藏下拉布局。如下圖所示: 代碼很簡單,就是一些圖片的顯示與進度條的隱藏,布局的設置padding等,這裡就不多說了。代碼裡都有給出。 MainActivity中的代碼如下所示:
package com.example.zq.pullfresh;
import android.support.v7.app.AppCompatActivity; import android.os.Bundle;
import java.util.ArrayList; import java.util.List; import java.util.Random;
public class MainActivity extends AppCompatActivity {
private List lists = new ArrayList<>();// TODO: 2016/4/26 聲明一個集合保存數據 private MyListView myListView;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO: 2016/4/26 設置該Activity的使用布局
setContentView(R.layout.activity_main);
lists.add("a");// TODO: 2016/4/26 象征性的添加幾個數據
lists.add("b");
lists.add("c");
// TODO: 2016/4/26 創建adapter
final MyAdapter adapter = new MyAdapter(MainActivity.this, lists);
// TODO: 2016/4/26 獲取自定義的listView
myListView = (MyListView)findViewById(R.id.myListView);
// TODO: 2016/4/26 設置adapter
myListView.setAdapter(adapter);
myListView.setOnRefreshingListener(new onRefreshingListener() {
@Override
public void onRefreshing(final MyListView myListView) {
new Thread(){
@Override
public void run() {
super.run();
try {
Thread.sleep(1000);
lists.add(new Random().nextInt(100)+"聯網獲取的數據");
// TODO: 2016/4/26 主線程執行更新UI操作必須在主線程
runOnUiThread(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
// TODO: 2016/4/26 聯網完成了,隱藏下拉刷新布局
myListView.completeRefresh();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
}); } }
代碼很簡單,獲取MyListVIew對象,給對象設置adapter。這樣就可以了。獲取adapter只需要創建MyAdapter類的對象可以獲取。MyAdapter類代碼如下:
package com.example.zq.pullfresh;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by zq on 2016/4/26.
*/
public class MyAdapter extends BaseAdapter {
private List lists = new ArrayList<>();
private Context context;
public MyAdapter(Context context, List lists) {
this.lists = lists;
this.context = context;
}
@Override
public int getCount() {
return lists.size();
}
@Override
public Object getItem(int position) {
return lists.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tvData = new TextView(context);// TODO: 2016/4/26 新建一個TextView
tvData.setText(lists.get(position));// TODO: 2016/4/26 設置數據
tvData.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);// TODO: 2016/4/26 設置textView在listView中的字體顯示位置
return tvData;// TODO: 2016/4/26 返回tvData
}
}
代碼簡單,繼承BaseAdapter,重寫相關方法,getView()方法中新建一個TextView,設置數據,返回TextView對象即可。 好了,到這裡就結束了。 最後給大家顯示一些演示的demo圖片: -
源碼下載地址:安卓開發技術之下拉刷新的實現
此開源框架官網地址:https://github.com/astuetz/PagerSlidingTabStrip可以理解為配合ViewPager使用的交互式頁面指示器控
Gallery 的用法很簡單,百度一下一大堆。現在就結合1個效果的例子。 這個效果其實很簡單,設置未被選中的項,的透明度 周圍的看起來就會有點模糊vcD4KPH
如何使用ES文件浏覽器的遠程管理。ES文件浏覽器是在android手機上常見的手機文件管理器,在基本的文件功能之上,它還支持開啟其他設備通過WiFi遠程連接
1.什麼是分支使用分支意味著你可以從開發主線上分離開來(即脫離主分支),然後在不影響主線的同時繼續工作。這種機制在多人開發過程中非常有用,每個人只需要創建一個屬於自己的分