編輯:關於Android編程
樣式效果
/** * 初始化FooterView */ private void initFooterView() { footerView = View.inflate(getContext(), R.layout.layout_footer, null); //獲取自定義組件的寬 高 footerView.measure(0, 0); footerViewHeight = footerView.getMeasuredHeight(); //將頭部進行隱藏 footerView.setPadding(0, -footerViewHeight, 0, 0); //將FooterView添加到ListView的底部 addFooterView(footerView); }
private void init(){ setOnScrollListener(this); ..... }
定義一個boolean類型,用於判斷是否 加載更多
private boolean isLoadingMore = false; //當前是否正在處於加載更多
/** * scrollState的值: * 0 = SCROLL_STATE_IDLE: 閒置狀態,就是手指松開 * 1 = SCROLL_STATE_TOUCH_SCROLL: 手指觸摸滑動,就是按著來滑動 * 2 = SCROLL_STATE_FLING: 快速滑動後松開 */ @Override public void onScrollStateChanged(AbsListView view, int scrollState) { //Log.e("main", scrollState + ""); //當手指松開 並且 此時是ListView中的item是最後一條的時候 顯示FooterView //getCount獲取的是ListView的總的條數 if(scrollState == OnScrollListener.SCROLL_STATE_IDLE && getLastVisiblePosition() == (getCount() -1 ) && !isLoadingMore ){ isLoadingMore = true; footerView.setPadding(0, 0, 0, 0); //將列表移動到指定的Position處 setSelection(getCount()); //如果監聽不為空 則調用加載更多方法 if(listener!=null){ listener.onLoadingMore(); } } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { }
public interface OnRefreshListener{ //下來刷新的時候調用 void onPullRefresh(); //加載更多 void onLoadingMore(); }
private void initData() { 。。。。。 refLv.setOnRefreshListener(new OnRefreshListener() { public void onPullRefresh() { //Log.e("MainActivity", "進入正在刷新狀態,此時應請求服務器數據"); //需要聯網請求服務器數據,然後更新UI requestDataFromServer(false); } @Override public void onLoadingMore() { requestDataFromServer(true); } }); } /** * 模擬向服務器請求數據 * @param isLoadingMore 用於區分 是加載更多數據 還是下拉刷新 */ private void requestDataFromServer(final boolean isLoadingMore){ new Thread(){ public void run() { //模擬請求服務的一個時間長度 SystemClock.sleep(3000); //將數據添加到頭部 if(isLoadingMore){ list.add("加載更多的數據-1"); list.add("加載更多的數據-2"); list.add("加載更多的數據-3"); }else { list.add(0, "下拉刷新的數據"); } //更新UI handler.sendEmptyMessage(0); }; }.start(); }
/** * 完成刷新 重置為下拉刷新狀態 * 在請求完數據 更新Adapter之後 在UI線程中調用該方法 */ public void completeRefresh(){ if(isLoadingMore){ //重置FooterView狀態 footerView.setPadding(0, -footerViewHeight, 0, 0); isLoadingMore = false; }else{ //HeaderView狀態 //隱藏HeaderView headerView.setPadding(0, -headerViewHeight, 0, 0); //狀態改變 currentState = PULL_REFRESH; //ProgressBar隱藏 pb_rotate.setVisibility(View.INVISIBLE); //圖片顯示 iv_arrow.setVisibility(View.VISIBLE); tv_state.setText("下拉刷新"); tv_time.setText("最後刷新: " + getCurrentTime()); } }
自定義View
public class RefreshListView extends ListView implements OnScrollListener { private View headerView; //HeaderView private int headerViewHeight; //HeaderViewHeight private View footerView; // footerView private int footerViewHeight; // footerViewHeight private int downY ; //按下時 的 Y坐標點 private final int PULL_REFRESH = 0; //下拉刷新的狀態 private final int RELEASE_REFRESH = 1; //松開刷新的狀態 private final int REFRESHING = 2; //正在刷新的狀態 private int currentState = PULL_REFRESH; private ImageView iv_arrow; private ProgressBar pb_rotate; private TextView tv_state; private TextView tv_time; private boolean isLoadingMore = false; //當前是否正在處於加載更多 //旋轉動畫 private RotateAnimation upAnimation, downAnimation; public RefreshListView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public RefreshListView(Context context) { super(context); init(); } /** * 初始化ListView中的數據 */ private void init(){ setOnScrollListener(this); //初始化HeaderView initHeaderView(); //初始化動畫 initRotateAnimation(); //初始化FooterView initFooterView(); } /** * 初始化動畫 */ private void initRotateAnimation() { //向上的動畫 upAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); upAnimation.setDuration(300); upAnimation.setFillAfter(true); //向下的動畫 downAnimation = new RotateAnimation( -180, -360, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); downAnimation.setDuration(300); downAnimation.setFillAfter(true); } /** * 添加一個HeaderView */ private void initHeaderView() { //獲取頭部的布局 headerView = View.inflate(getContext(), R.layout.layout_header, null); iv_arrow = (ImageView) headerView.findViewById(R.id.iv_arrow); pb_rotate = (ProgressBar) headerView.findViewById(R.id.pb_rotate); tv_state = (TextView) headerView.findViewById(R.id.tv_state); tv_time = (TextView) headerView.findViewById(R.id.tv_time); //獲取自定義組件的寬 高 headerView.measure(0, 0); headerViewHeight = headerView.getMeasuredHeight(); //將頭部進行隱藏 headerView.setPadding(0, -headerViewHeight, 0, 0); //將頭部添加到RefreshListView中 addHeaderView(headerView); } /** * 初始化FooterView */ private void initFooterView() { footerView = View.inflate(getContext(), R.layout.layout_footer, null); //獲取自定義組件的寬 高 footerView.measure(0, 0); footerViewHeight = footerView.getMeasuredHeight(); //將頭部進行隱藏 footerView.setPadding(0, -footerViewHeight, 0, 0); //將FooterView添加到ListView的底部 addFooterView(footerView); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: downY = (int) ev.getY(); break; case MotionEvent.ACTION_MOVE: //如果在刷新中的話 就不讓操作了 if(currentState == REFRESHING){ break; } //獲取到移動的大小 int delaY = (int)(ev.getY() - downY) ; //計算出新的headerViewHeight int paddingTop = -headerViewHeight + delaY; if(paddingTop > -headerViewHeight && getFirstVisiblePosition() == 0){ headerView.setPadding(0, paddingTop, 0, 0); if(paddingTop >= 0 &¤tState == PULL_REFRESH){ //下拉刷新狀態 進入松開刷新狀態 currentState = RELEASE_REFRESH; refreshHeaderView(); }else if(paddingTop < 0 && currentState == RELEASE_REFRESH){ //松開刷新狀態 進入下拉刷新狀態 currentState = PULL_REFRESH; refreshHeaderView(); } //攔截TouchMove,不讓listview處理該次move事件,會造成listview無法滑動 return true; } break; case MotionEvent.ACTION_UP: if(currentState == PULL_REFRESH){ //隱藏HeaderView headerView.setPadding(0, -headerViewHeight, 0, 0); }else if(currentState == RELEASE_REFRESH){ headerView.setPadding(0, 0, 0, 0); currentState = REFRESHING; refreshHeaderView(); //模擬延時 // new Handler().postDelayed(new Runnable() { // // @Override // public void run() { // completeRefresh(); // } // }, 3000); if(listener != null){ listener.onPullRefresh(); } } break; } return super.onTouchEvent(ev); } /** * 根據 currentState 來更新 HeaderView */ private void refreshHeaderView(){ switch (currentState) { case PULL_REFRESH: //下拉刷新的狀態 tv_state.setText("下拉刷新"); iv_arrow.startAnimation(downAnimation); break; case RELEASE_REFRESH: //松開刷新的狀態 tv_state.setText("松開刷新"); iv_arrow.startAnimation(upAnimation); break; case REFRESHING://正在刷新的狀態 //清除動畫 可能動畫未執行完畢 所以需要清除動畫 iv_arrow.clearAnimation(); //讓圖標隱藏 iv_arrow.setVisibility(View.INVISIBLE); //ProgressBar 顯示可見 pb_rotate.setVisibility(View.VISIBLE); tv_state.setText("正在刷新..."); break; } } /** * 完成刷新 重置為下拉刷新狀態 * 在請求完數據 更新Adapter之後 在UI線程中調用該方法 */ public void completeRefresh(){ if(isLoadingMore){ //重置FooterView狀態 footerView.setPadding(0, -footerViewHeight, 0, 0); isLoadingMore = false; }else{ //HeaderView狀態 //隱藏HeaderView headerView.setPadding(0, -headerViewHeight, 0, 0); //狀態改變 currentState = PULL_REFRESH; //ProgressBar隱藏 pb_rotate.setVisibility(View.INVISIBLE); //圖片顯示 iv_arrow.setVisibility(View.VISIBLE); tv_state.setText("下拉刷新"); tv_time.setText("最後刷新: " + getCurrentTime()); } } /** * 獲取當前時間 * @return */ private String getCurrentTime(){ SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); return format.format(new Date()); } /** * 定義刷新監聽接口,用於處理刷新過程中業務邏輯請求的處理 * @author Denny * @date 2016-4-26 */ public interface OnRefreshListener{ //下來刷新的時候調用 void onPullRefresh(); //加載更多 void onLoadingMore(); } private OnRefreshListener listener; public void setOnRefreshListener( OnRefreshListener listener){ this.listener = listener; } /** * scrollState的值: * 0 = SCROLL_STATE_IDLE: 閒置狀態,就是手指松開 * 1 = SCROLL_STATE_TOUCH_SCROLL: 手指觸摸滑動,就是按著來滑動 * 2 = SCROLL_STATE_FLING: 快速滑動後松開 */ @Override public void onScrollStateChanged(AbsListView view, int scrollState) { //Log.e("main", scrollState + ""); //當手指松開 並且 此時是ListView中的item是最後一條的時候 顯示FooterView //getCount獲取的是ListView的總的條數 if(scrollState == OnScrollListener.SCROLL_STATE_IDLE && getLastVisiblePosition() == (getCount() -1 ) && !isLoadingMore ){ isLoadingMore = true; footerView.setPadding(0, 0, 0, 0); //將列表移動到指定的Position處 setSelection(getCount()); //如果監聽不為空 則調用加載更多方法 if(listener!=null){ listener.onLoadingMore(); } } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }
MainActivity
public class MainActivity extends Activity { private RefreshListView refLv; private ArrayListlist = new ArrayList (); private MyAdapter myAdapter; private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { //更新UI myAdapter.notifyDataSetChanged(); //重置狀態 refLv.completeRefresh(); }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initView(); initData(); } /** * 初始化View */ private void initView() { setContentView(R.layout.activity_main); refLv = (RefreshListView) findViewById(R.id.refLv); } /** * 初始化數據 */ private void initData() { for (int i = 0; i < 15; i++) { list.add("ListView原來數據 :" + i); } //獲取頭部的布局 // final View headerView = View.inflate(MainActivity.this, // R.layout.layout_header, null); //1、第一種 獲取自動加載View的高度的方式 使用監聽的方式 // //使用inflate是異步的 要想獲取到加載組件的高度 需要使用 getViewTreeObserver 進行監聽 // headerView.getViewTreeObserver().addOnGlobalLayoutListener( // new OnGlobalLayoutListener() { // // @Override // public void onGlobalLayout() { // // //要先remove掉一下 // headerView.getViewTreeObserver().removeGlobalOnLayoutListener(this); // // //獲取頭部布局的高度 // int headerViewHeight = headerView.getHeight(); // //將頭部進行隱藏 // headerView.setPadding(0, -headerViewHeight, 0, 0); // refLv.addHeaderView(headerView); // } // }); // 第 一種 獲取動態 自定義組件的寬 高 // headerView.measure(0, 0); //自動的通知系統獲取高度和寬度 // int headerViewHeight = headerView.getMeasuredHeight(); // //將頭部進行隱藏 // headerView.setPadding(0, -headerViewHeight, 0, 0); // refLv.addHeaderView(headerView); myAdapter = new MyAdapter(); refLv.setAdapter(myAdapter); refLv.setOnRefreshListener(new OnRefreshListener() { public void onPullRefresh() { //Log.e("MainActivity", "進入正在刷新狀態,此時應請求服務器數據"); //需要聯網請求服務器數據,然後更新UI requestDataFromServer(false); } @Override public void onLoadingMore() { requestDataFromServer(true); } }); } /** * 模擬向服務器請求數據 * @param isLoadingMore 用於區分 是加載更多數據 還是下拉刷新 */ private void requestDataFromServer(final boolean isLoadingMore){ new Thread(){ public void run() { //模擬請求服務的一個時間長度 SystemClock.sleep(3000); //將數據添加到頭部 if(isLoadingMore){ list.add("加載更多的數據-1"); list.add("加載更多的數據-2"); list.add("加載更多的數據-3"); }else { list.add(0, "下拉刷新的數據"); } //更新UI handler.sendEmptyMessage(0); }; }.start(); } class MyAdapter extends BaseAdapter { @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { TextView tv = new TextView(MainActivity.this); tv.setPadding(20, 20, 20, 20); tv.setTextSize(18); tv.setText(list.get(position)); return tv; } } }
1)首先先將gitlab上的開發項目clone到本地(可以使用命令行或者管理工具,具體操作在GitLab中已經涉及,這裡不再贅述),然後導入到AndroidStudio中
這一個知識點主要以理解為主:一、任務棧(task stack)1、作用:就是用來管理activity的進入,退出。記錄了用戶的行為。2、舉例:假如要進行一下操作:這時候,
RecyclerView是什麼?筆者個人看法,RecyclerView只是一個對ListView的升級版,這個升級的主要目的是為了讓這個view的效率更高,並且使用更加方
效果圖如下:默認第一次加載選擇原始隊列:級聯效果圖:關鍵代碼給下拉列表選中事件監聽綁定Id :復制代碼 代碼如下:int pos = firsthand_dlbh_pin