編輯:關於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 ArrayList list = 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;
}
}
}
Android開發之Android studio使用git gitlab(二)
1)首先先將gitlab上的開發項目clone到本地(可以使用命令行或者管理工具,具體操作在GitLab中已經涉及,這裡不再贅述),然後導入到AndroidStudio中
(Android review) 任務棧與啟動模式
這一個知識點主要以理解為主:一、任務棧(task stack)1、作用:就是用來管理activity的進入,退出。記錄了用戶的行為。2、舉例:假如要進行一下操作:這時候,
Android RecyclerView布局就這麼簡單
RecyclerView是什麼?筆者個人看法,RecyclerView只是一個對ListView的升級版,這個升級的主要目的是為了讓這個view的效率更高,並且使用更加方
android 之Spinner下拉菜單實現級聯
效果圖如下:默認第一次加載選擇原始隊列:級聯效果圖:關鍵代碼給下拉列表選中事件監聽綁定Id :復制代碼 代碼如下:int pos = firsthand_dlbh_pin