編輯:關於Android編程
沒有辦法,米公設計的一個UI是stickyheaderlist(頭部停留)和分頁加載數據功能的整合,筆者原以為是米工自己拍著腦袋想出來的,還想進一步討論一下,後來才發現支付寶也是這麼做的,那好吧,做呗。
先上Demo完成效果圖(有點簡陋,但是這樣代碼卻也更清晰了)
下面分別介紹一下StickyHeaderListView(這麼長!後面都簡寫成StickyLV好了)和分頁加載:
一、StickyLV(頭部停留listview)
其實這個沒什麼好說的,因為是開源組件,github上都有介紹和demo,這裡就簡單的講一下幾個關鍵的地方吧
a.StickyLV的對應的Adapter要繼承StickyListHeadersAdapter接口,並實現其中的getHeaderView和getHeaderId方法,前者和普通的Adapter的getView方法一樣,需要注意的是後者,只有在返回的int值和上一個返回值不同時,才會顯示HeaderView,同時,要將返回值的計算式關聯到position上。
b.同樣在StickyLV對應的Adapter中,盡管為StickyLV添加了HeaderView,但是getCount()返回的仍然是內容列表項的數量,而不包括HeaderView的數量。
二、分頁加載更多數據
a.首先分頁加載通常出現在服務器數據請求中,因為一次性加載過多的數據可能會帶來不好的用戶體驗,及不要的性能開銷。所以通過分頁加載來平滑加載過程。
b.分頁數據加載事件由listview觸發,主要通過重寫onScrollStateChanged方法來實現。
c.最後定義一個OnLoadingMoreListener接口,在其中定義一個加載數據的方法OnLoadingMore。並將接口作為參數由外部調用進行初始化動作,這就是所謂的代理或者說監聽者模式。
d.最後還有footerView的定義、添加及隱藏。
主要實現代碼
StickyListAdapter:
package com.wly.sticky_pagelist; import java.util.ArrayList; import android.content.Context; import android.graphics.Color; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import com.emilsjolander.components.stickylistheaders.StickyListHeadersAdapter; public class StickyListAdapter extends BaseAdapter implements StickyListHeadersAdapter { private ArrayListlist; private Context mContext; public void init(Context context,ArrayList list) { this.list = list; this.mContext = context; mContext = context; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { TextView itemView = new TextView(mContext); itemView.setText("Item:" + position); itemView.setTextSize(20); return itemView; } @Override public View getHeaderView(int position, View convertView, ViewGroup parent) { TextView headView = new TextView(mContext); headView.setText("Head:" + (position/10)); headView.setTextSize(24); headView.setTextColor(new Color().RED); return headView; } /** * 決定header出現的時機,如果當前的headerid和前一個headerid不同時,就會顯示 */ @Override public long getHeaderId(int position) { return position/10 + 0x1234; } }
在導入的StickyListHeadersListView中定義接口OnLoadingMoreListener
/** * 加載更多數據回調接口 * */ public interface OnLoadingMoreLinstener { /** * 加載更多數據回調方法,由組件自身觸發 */ void OnLoadingMore(); }
並修改StickyListHeadersListView的mOnScrollListener接口對象的onScrollStateChanged方法,如下:
public OnScrollListener mOnScrollListener = new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { Log.e("parent","onScrollStateChanged"); if (mOnScrollListenerDelegate != null) { mOnScrollListenerDelegate.onScrollStateChanged(view, scrollState); } // 滑到底部後自動加載,判斷listview已經停止滾動並且最後可視的條目等於adapter的條目 if (scrollState == OnScrollListener.SCROLL_STATE_FLING) { } else if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL || scrollState == OnScrollListener.SCROLL_STATE_IDLE) { if (getLastVisiblePosition() == (getCount() - 1)) { Log.e("Sticky","--拖動到最後--"); if(loadMoreListener != null) { loadMoreListener.OnLoadingMore(); } } } }
最後,界面MainActivity
package com.wly.sticky_pagelist; import java.util.ArrayList; public class MainActivity extends Activity implements OnHeaderClickListener,AdapterView.OnItemClickListener ,OnLoadingMoreLinstener { private LayoutInflater inflater; ArrayListlist; StickyListAdapter adapter; StickyListHeadersListView stickyLV; private RelativeLayout moredata; private View progressBarView; private TextView progressBarTextView; private AnimationDrawable loadingAnimation; //加載更多,動畫 private boolean isLoading = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); list = new ArrayList (); for(int i=1;i<=15;i++) { list.add(i + ""); } adapter = new StickyListAdapter(); adapter.init(this, list); inflater = LayoutInflater.from(this); moredata = (RelativeLayout)inflater.inflate(R.layout.moredata, null); stickyLV = (StickyListHeadersListView)this.findViewById(R.id.stickyList); progressBarView = (View) moredata.findViewById(R.id.loadmore_foot_progressbar); progressBarTextView = (TextView) moredata.findViewById(R.id.loadmore_foot_text); loadingAnimation = (AnimationDrawable) progressBarView.getBackground(); stickyLV.addFooterView(moredata); stickyLV.setAdapter(adapter); stickyLV.setOnItemClickListener(this); stickyLV.setOnHeaderClickListener(this); stickyLV.setLoadingMoreListener(this); } public void loadingFinished() { if (null != loadingAnimation && loadingAnimation.isRunning()) { loadingAnimation.stop(); } progressBarView.setVisibility(View.INVISIBLE); progressBarTextView.setVisibility(View.INVISIBLE); isLoading = false; adapter.notifyDataSetChanged(); } @Override public void OnLoadingMore() { progressBarView.setVisibility(View.VISIBLE); progressBarTextView.setVisibility(View.VISIBLE); loadingAnimation.start(); if(!isLoading) { isLoading = true; new Handler().postDelayed(new Runnable() { @Override public void run() { for(int i=0;i<5;i++) { list.add((Math.random() * 40) + ""); } loadingFinished(); } },1200); } } @Override public void onHeaderClick(StickyListHeadersListView l, View header, int itemPosition, long headerId, boolean currentlySticky) { Toast.makeText(this, "header:" + headerId, Toast.LENGTH_SHORT).show(); } @Override public void onItemClick(AdapterView> parent, View view, int position, long id) { Toast.makeText(this, "item:" + position, Toast.LENGTH_SHORT).show(); } }
參考文檔:https://github.com/emilsjolander/StickyListHeaders
完整工程下載:http://download.csdn.net/detail/u011638883/7062457
O啦~~~
裝載請保留出處:http://blog.csdn.net/u011638883/article/details/21316779
謝謝!!
一、 Android Studio配置SVN Android Studio關聯配置SVN很簡單,在Settings裡面,找到Version Control->Sub
相關概念1.Handler:可以看做是一個工具類,用來向消息隊列中插入消息的;2.Thread:所有與Handler相關的功能都是與Thread密不可分的,Handler
前面文章介紹了Activity以及Intent的使用,本文就來介紹Service。如果把Activity比喻為前台程序,那麼Service就是後台程序,Service的整
模塊實現前,先說兩點:第一點、登陸模塊的實現,是多數APP的基礎功能。第二點、數據庫用的不是MySQL,Oracle等,Android項目,多數還是會用到SQLite.現