編輯:關於Android編程
趁著周一休息,更新一下博客。最近項目中使用到了分組管理,需要實現Listview的Item拖動處理。查略一下資料和借鑒了別人的代碼將功能實現了。現在整理一下代碼,方便自己以後學習具體思路如下
重寫ListView的onInterceptTouchEvent方法進行控件的touch事件攔截
這個方法的作用很簡單:當我們摁下的如果是可拖拽的圖標,那麼進行初始化該Item的映像試視圖。
同時在拖動中判斷拖動的距離,具體查看下面代碼。不是則不進行處理。代碼如下(代碼注釋非常清楚,如果還有不懂的地方可以在下面留言,我們一起討論,或者下載源碼,自己好好研究一下)
package com.pengguichu.testdraglistview.listview;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import com.pengguichu.testdraglistview.R;
import com.pengguichu.testdraglistview.adapter.DragListAdapter;
import com.pengguichu.testdraglistview.entiy.DragItemInfo;
/**
* 自定義可拖動Item排序ListView
*
* @author guichupeng
*
*/
@SuppressLint({ "NewApi", "HandlerLeak" })
public class DragListView extends ListView {
private ImageView mDragImageView;// 被拖拽的項(item),其實就是一個ImageView
private int mStartPosition;// 手指拖動項原始在列表中的位置
private int mDragPosition;// 手指點擊准備拖動的時候,當前拖動項在列表中的位置
private int mLastPosition;// 手指點擊准備拖動的時候,當前拖動項在列表中的位置
private int mDragPoint;// 在當前數據項中的位置
private int mDragOffset;// 當前視圖和屏幕的距離(這裡只使用了y方向上)
private int mUpScrollBounce;// 拖動的時候,開始向上滾動的邊界
private int mDownScrollBounce;// 拖動的時候,開始向下滾動的邊界
private final static int mStep = 1;// ListView 滑動步伐
private int mCurrentStep;// 當前步伐
private DragItemInfo mDragItemInfo;// 用於存放Item信息的對象
private int mItemVerticalSpacing = 0;// Item垂直區域空間
private int mHoldPosition;// 標記最後停靠的Position
/** windows窗口控制類 */
private WindowManager mWindowManager;
/** 用於控制拖拽項的顯示的參數 */
private WindowManager.LayoutParams mWindowParams;
/** 停止狀態 */
public static final int MSG_DRAG_STOP = 0x1001;
/** 移動狀態 */
public static final int MSG_DRAG_MOVE = 0x1002;
/** 動畫時長(一個動畫的耗時) */
private static final int ANIMATION_DURATION = 200;
/** 標識是否上鎖 */
private boolean isLock;
/** 標識是否處於移動狀態 */
private boolean isMoving = false;
/** 是否拖動Item */
private boolean isDragItemMoving = false;
/** 標識是否獲取到間距 */
private boolean bHasGetSapcing = false;
public DragListView(Context context, AttributeSet attrs) {
super(context, attrs);
setLayerType(View.LAYER_TYPE_HARDWARE, null);
mDragItemInfo = new DragItemInfo();
init();
}
/**
* 初始化
*/
private void init() {
mWindowManager = (WindowManager) getContext()
.getSystemService("window");
}
/**
* 接收消息並完成對應動作
*/
Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case MSG_DRAG_STOP:// 停止
stopDrag();
onDrop(msg.arg1);
break;
case MSG_DRAG_MOVE:// 移動
onDrag(msg.arg1);
break;
}
};
};
/**
* 獲取間距--獲取上下滾動間距
*/
private void getSpacing() {
bHasGetSapcing = true;
mUpScrollBounce = getHeight() / 3;// 取得向上滾動的邊際,大概為該控件的1/3
mDownScrollBounce = getHeight() * 2 / 3;// 取得向下滾動的邊際,大概為該控件的2/3
int[] firstTempLocation = new int[2];
int[] secondTempLocation = new int[2];
ViewGroup firstItemView = (ViewGroup) getChildAt(0);// 第一行
ViewGroup secondItemView = (ViewGroup) getChildAt(1);// 第二行
if (firstItemView != null) {
firstItemView.getLocationOnScreen(firstTempLocation);
} else {
return;
}
if (secondItemView != null) {
secondItemView.getLocationOnScreen(secondTempLocation);
mItemVerticalSpacing = Math.abs(secondTempLocation[1]
- firstTempLocation[1]);
} else {
return;
}
}
/***
* touch事件攔截 在這裡我進行相應攔截,
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// 按下
if (ev.getAction() == MotionEvent.ACTION_DOWN && !isLock && !isMoving
&& !isDragItemMoving) {
int x = (int) ev.getX();// 獲取相對與ListView的x坐標
int y = (int) ev.getY();// 獲取相應與ListView的y坐標
mLastPosition = mStartPosition = mDragPosition = pointToPosition(x,
y);
// 無效不進行處理
if (mDragPosition == AdapterView.INVALID_POSITION) {
return super.onInterceptTouchEvent(ev);
}
if (false == bHasGetSapcing) {
getSpacing();
}
// 獲取當前位置的視圖(可見狀態)
ViewGroup dragger = (ViewGroup) getChildAt(mDragPosition
- getFirstVisiblePosition());
DragListAdapter adapter = (DragListAdapter) getAdapter();
mDragItemInfo.obj = adapter.getItem(mDragPosition
- getFirstVisiblePosition());
// 獲取到的dragPoint其實就是在你點擊指定item項中的高度.
mDragPoint = y - dragger.getTop();
// 這個值是固定的:其實就是ListView這個控件與屏幕最頂部的距離(一般為標題欄+狀態欄).
mDragOffset = (int) (ev.getRawY() - y);
// 獲取可拖拽的圖標
View draggerIcon = dragger.findViewById(R.id.drag_item_image);
if (draggerIcon.getVisibility() == View.VISIBLE) {// 只有在按鈕為可見的情況下才允許移動
// x > dragger.getLeft() - 20這句話為了更好的觸摸(-20可以省略)
if (draggerIcon != null && x > draggerIcon.getLeft() - 20) {
dragger.destroyDrawingCache();
dragger.setDrawingCacheEnabled(true);// 開啟cache.
dragger.setBackgroundColor(0xffefefef);
Bitmap bm = Bitmap.createBitmap(dragger
.getDrawingCache(true));// 根據cache創建一個新的bitmap對象.
hideDropItem();
adapter.setInvisiblePosition(mStartPosition);
adapter.notifyDataSetChanged();
startDrag(bm, y);// 初始化影像
isMoving = false;
adapter.copyList();
}
}
}
return super.onInterceptTouchEvent(ev);
}
/**
* 獲取依個縮放動畫
*
* @return
*/
public Animation getScaleAnimation() {
Animation scaleAnimation = new ScaleAnimation(0.0f, 0.0f, 0.0f, 0.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
scaleAnimation.setFillAfter(true);
return scaleAnimation;
}
/**
* 隱藏下降的Item
*/
private void hideDropItem() {
final DragListAdapter adapter = (DragListAdapter) this.getAdapter();
adapter.showDropItem(false);
}
/**
* 觸摸事件處理
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
// item的view不為空,且獲取的dragPosition有效
if (mDragImageView != null && mDragPosition != INVALID_POSITION
&& !isLock) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_UP:
int upY = (int) ev.getY();
stopDrag();
onDrop(upY);
break;
case MotionEvent.ACTION_MOVE:
int moveY = (int) ev.getY();
onDrag(moveY);
itemMoveAnimation(moveY);
break;
case MotionEvent.ACTION_DOWN:
break;
}
return true;// 取消ListView滑動.
}
return super.onTouchEvent(ev);
}
/**
* 是否為相同方向拖動的標記
*/
private boolean isSameDragDirection = true;
/**
* 移動方向的標記,-1為默認值,0表示向下移動,1表示向上移動
*/
private int lastFlag = -1;
private int mFirstVisiblePosition, mLastVisiblePosition;// 第一個、最後一個的位置
private int turnUpPosition, turnDownPosition;// 向上、下的位置
/**
* 動態改變Item內容
*
* @param last
* // 最後一項的位置
* @param current
* // 當前位置
*/
private void onChangeCopy(int last, int current) {
DragListAdapter adapter = (DragListAdapter) getAdapter();
if (last != current) {// 判斷是否移動到最後一項
adapter.exchangeCopy(last, current);
}
}
/**
* Item移動動畫
*
* @param y
*/
private void itemMoveAnimation(int y) {
final DragListAdapter adapter = (DragListAdapter) getAdapter();
int tempPosition = pointToPosition(0, y);
if (tempPosition == INVALID_POSITION || tempPosition == mLastPosition) {
return;
}
mFirstVisiblePosition = getFirstVisiblePosition();
mDragPosition = tempPosition;
onChangeCopy(mLastPosition, mDragPosition);
int MoveNum = tempPosition - mLastPosition;// 計算移動項--移動距離
int count = Math.abs(MoveNum);
for (int i = 1; i <= count; i++) {
int xAbsOffset, yAbsOffset;
// 向下拖動
if (MoveNum > 0) {
if (lastFlag == -1) {
lastFlag = 0;
isSameDragDirection = true;
}
if (lastFlag == 1) {
turnUpPosition = tempPosition;
lastFlag = 0;
isSameDragDirection = !isSameDragDirection;
}
if (isSameDragDirection) {
mHoldPosition = mLastPosition + 1;
} else {
if (mStartPosition < tempPosition) {
mHoldPosition = mLastPosition + 1;
isSameDragDirection = !isSameDragDirection;
} else {
mHoldPosition = mLastPosition;
}
}
xAbsOffset = 0;
yAbsOffset = -mItemVerticalSpacing;
mLastPosition++;
} else {// 向上拖動
if (lastFlag == -1) {
lastFlag = 1;
isSameDragDirection = true;
}
if (lastFlag == 0) {
turnDownPosition = tempPosition;
lastFlag = 1;
isSameDragDirection = !isSameDragDirection;
}
if (isSameDragDirection) {
mHoldPosition = mLastPosition - 1;
} else {
if (mStartPosition > tempPosition) {
mHoldPosition = mLastPosition - 1;
isSameDragDirection = !isSameDragDirection;
} else {
mHoldPosition = mLastPosition;
}
}
xAbsOffset = 0;
yAbsOffset = mItemVerticalSpacing;
mLastPosition--;
}
adapter.setHeight(mItemVerticalSpacing);
adapter.setIsSameDragDirection(isSameDragDirection);
adapter.setLastFlag(lastFlag);
ViewGroup moveView = (ViewGroup) getChildAt(mHoldPosition
- getFirstVisiblePosition());
Animation animation;
if (isSameDragDirection) {// 相同方向拖動
animation = getFromSelfAnimation(xAbsOffset, yAbsOffset);
} else {// 不相同方向拖動
animation = getToSelfAnimation(xAbsOffset, -yAbsOffset);
}
// 啟用對應的動畫
moveView.startAnimation(animation);
}
}
private void onDrop(int x, int y) {
final DragListAdapter adapter = (DragListAdapter) getAdapter();
adapter.setInvisiblePosition(-1);
adapter.showDropItem(true);
adapter.notifyDataSetChanged();
}
/**
* 准備拖動,初始化拖動項的圖像
*
* @param bm
* @param y
*/
private void startDrag(Bitmap bm, int y) {
/***
* 初始化window.
*/
mWindowParams = new WindowManager.LayoutParams();
mWindowParams.gravity = Gravity.TOP;
mWindowParams.x = 0;
mWindowParams.y = y - mDragPoint + mDragOffset;
mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE// 不需獲取焦點
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE// 不需接受觸摸事件
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON// 保持設備常開,並保持亮度不變。
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;// 窗口占滿整個屏幕,忽略周圍的裝飾邊框(例如狀態欄)。此窗口需考慮到裝飾邊框的內容。
// windowParams.format = PixelFormat.TRANSLUCENT;// 默認為不透明,這裡設成透明效果.
mWindowParams.windowAnimations = 0;// 窗口所使用的動畫設置
mWindowParams.alpha = 0.8f;
mWindowParams.format = PixelFormat.TRANSLUCENT;
ImageView imageView = new ImageView(getContext());
imageView.setImageBitmap(bm);
mWindowManager.addView(imageView, mWindowParams);
mDragImageView = imageView;
}
/**
* 拖動執行,在Move方法中執行
*
* @param y
*/
public void onDrag(int y) {
int drag_top = y - mDragPoint;// 拖拽view的top值不能<0,否則則出界.
if (mDragImageView != null && drag_top >= 0) {
mWindowParams.alpha = 1.0f;
mWindowParams.y = y - mDragPoint + mDragOffset;
mWindowManager.updateViewLayout(mDragImageView, mWindowParams);// 時時移動.
}
doScroller(y);// listview移動.
}
/***
* ListView的移動.
* 要明白移動原理:當我移動到下端的時候,ListView向上滑動,當我移動到上端的時候,ListView要向下滑動。正好和實際的相反.
*
*/
public void doScroller(int y) {
// ListView需要下滑
if (y < mUpScrollBounce) {
mCurrentStep = mStep + (mUpScrollBounce - y) / 10;// 時時步伐
}// ListView需要上滑
else if (y > mDownScrollBounce) {
mCurrentStep = -(mStep + (y - mDownScrollBounce)) / 10;// 時時步伐
} else {
mCurrentStep = 0;
}
// 獲取你拖拽滑動到位置及顯示item相應的view上(注:可顯示部分)(position)
View view = getChildAt(mDragPosition - getFirstVisiblePosition());
// 真正滾動的方法setSelectionFromTop()
setSelectionFromTop(mDragPosition, view.getTop() + mCurrentStep);
}
/**
* 停止拖動,刪除影像
*/
public void stopDrag() {
isMoving = false;
if (mDragImageView != null) {
mWindowManager.removeView(mDragImageView);
mDragImageView = null;
}
isSameDragDirection = true;
lastFlag = -1;
DragListAdapter adapter = (DragListAdapter) getAdapter();
adapter.setLastFlag(lastFlag);
adapter.pastList();
}
/**
* 拖動放下的時候
*
* @param y
*/
public void onDrop(int y) {
onDrop(0, y);
}
/**
* 獲取自身出現的動畫
*
* @param x
* @param y
* @return
*/
private Animation getFromSelfAnimation(int x, int y) {
TranslateAnimation translateAnimation = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.ABSOLUTE, x,
Animation.RELATIVE_TO_SELF, 0, Animation.ABSOLUTE, y);
translateAnimation
.setInterpolator(new AccelerateDecelerateInterpolator());
translateAnimation.setFillAfter(true);
translateAnimation.setDuration(ANIMATION_DURATION);
translateAnimation.setInterpolator(new AccelerateInterpolator());
return translateAnimation;
}
/**
* 獲取自身離開的動畫
*
* @param x
* @param y
* @return
*/
private Animation getToSelfAnimation(int x, int y) {
TranslateAnimation translateAnimation = new TranslateAnimation(
Animation.ABSOLUTE, x, Animation.RELATIVE_TO_SELF, 0,
Animation.ABSOLUTE, y, Animation.RELATIVE_TO_SELF, 0);
translateAnimation
.setInterpolator(new AccelerateDecelerateInterpolator());
translateAnimation.setFillAfter(true);
translateAnimation.setDuration(ANIMATION_DURATION);
translateAnimation.setInterpolator(new AccelerateInterpolator());
return translateAnimation;
}
}
package com.pengguichu.testdraglistview.adapter;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.pengguichu.testdraglistview.R;
/**
* 自定義可拖拽ListView適配器
* @author guichupeng 下午1:15:31
*/
public class DragListAdapter extends BaseAdapter {
private List mDataList;// 標題數組
private Context mContext;
/**
* DragListAdapter構造方法
*
* @param context
* // 上下文對象
* @param dataList
* // 數據集合
*/
public DragListAdapter(Context context, ArrayList dataList) {
this.mContext = context;
this.mDataList = dataList;
}
/**
* 設置是否顯示下降的Item
*
* @param showItem
*/
public void showDropItem(boolean showItem) {
this.mShowItem = showItem;
}
/**
* 設置不可見項的位置標記
*
* @param position
*/
public void setInvisiblePosition(int position) {
mInvisilePosition = position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
/***
* 在這裡盡可能每次都進行實例化新的,這樣在拖拽ListView的時候不會出現錯亂.
* 具體原因不明,不過這樣經過測試,目前沒有發現錯亂。雖說效率不高,但是做拖拽LisView足夠了。
*/
convertView = LayoutInflater.from(mContext).inflate(
R.layout.drag_list_item, null);
initItemView(position, convertView);
TextView titleTv = (TextView) convertView
.findViewById(R.id.drag_item_title_tv);
titleTv.setText(mDataList.get(position));
if (isChanged) {// 判斷是否發生了改變
if (position == mInvisilePosition) {
if (!mShowItem) {// 在拖拽過程不允許顯示的狀態下,設置Item內容隱藏
// 因為item背景為白色,故而在這裡要設置為全透明色防止有白色遮擋問題(向上拖拽)
convertView.findViewById(R.id.drag_item_layout)
.setBackgroundColor(0x0000000000);
// 隱藏Item上面的內容
int vis = View.INVISIBLE;
convertView.findViewById(R.id.drag_item_image)
.setVisibility(vis);
convertView.findViewById(R.id.drag_item_close_layout)
.setVisibility(vis);
titleTv.setVisibility(vis);
}
}
if (mLastFlag != -1) {
if (mLastFlag == 1) {
if (position > mInvisilePosition) {
Animation animation;
animation = getFromSelfAnimation(0, -mHeight);
convertView.startAnimation(animation);
}
} else if (mLastFlag == 0) {
if (position < mInvisilePosition) {
Animation animation;
animation = getFromSelfAnimation(0, mHeight);
convertView.startAnimation(animation);
}
}
}
}
return convertView;
}
/**
*
* 初始化Item視圖
*
* @param convertView
*/
private void initItemView(final int position, final View convertView) {
if (convertView != null) {
// 設置對應的監聽
convertView.findViewById(R.id.drag_item_close_layout)
.setOnClickListener(new OnClickListener() {// 刪除
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
removeItem(position);
}
});
}
}
private int mInvisilePosition = -1;// 用來標記不可見Item的位置
private boolean isChanged = true;// 標識是否發生改變
private boolean mShowItem = false;// 標識是否顯示拖拽Item的內容
/***
* 動態修改ListView的方位.
*
* @param startPosition
* 點擊移動的position
* @param endPosition
* 松開時候的position
*/
public void exchange(int startPosition, int endPosition) {
Object startObject = getItem(startPosition);
if (startPosition < endPosition) {
mDataList.add(endPosition + 1, (String) startObject);
mDataList.remove(startPosition);
} else {
mDataList.add(endPosition, (String) startObject);
mDataList.remove(startPosition + 1);
}
isChanged = true;
}
/**
* 動態修改Item內容
*
* @param startPosition
* // 開始的位置
* @param endPosition
* // 當前停留的位置
*/
public void exchangeCopy(int startPosition, int endPosition) {
Object startObject = getCopyItem(startPosition);
if (startPosition < endPosition) {// 向下移動
mCopyList.add(endPosition + 1, (String) startObject);
mCopyList.remove(startPosition);
} else {// 向上拖動或者不動
mCopyList.add(endPosition, (String) startObject);
mCopyList.remove(startPosition + 1);
}
isChanged = true;
}
/**
* 刪除指定的Item
*
* @param pos
* // 要刪除的下標
*/
private void removeItem(int pos) {
if (mDataList != null && mDataList.size() > pos) {
mDataList.remove(pos);
this.notifyDataSetChanged();
}
}
/**
* 獲取鏡像(拖拽)Item項
*
* @param position
* @return
*/
public Object getCopyItem(int position) {
return mCopyList.get(position);
}
/**
* 獲取Item總數
*/
@Override
public int getCount() {
return mDataList.size();
}
/**
* 獲取ListView中Item項
*/
@Override
public Object getItem(int position) {
return mDataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
/**
* 添加拖動項
*
* @param start
* // 要進行添加的位置
* @param obj
*/
public void addDragItem(int start, Object obj) {
mDataList.remove(start);// 刪除該項
mDataList.add(start, (String) obj);// 添加刪除項
}
private ArrayList mCopyList = new ArrayList();
public void copyList() {
mCopyList.clear();
for (String str : mDataList) {
mCopyList.add(str);
}
}
public void pastList() {
mDataList.clear();
for (String str : mCopyList) {
mDataList.add(str);
}
}
private boolean isSameDragDirection = true;// 是否為相同方向拖動的標記
private int mLastFlag = -1;
private int mHeight;
private int mDragPosition = -1;
/**
* 設置是否為相同方向拖動的標記
*
* @param value
*/
public void setIsSameDragDirection(boolean value) {
isSameDragDirection = value;
}
/**
* 設置拖動方向標記
*
* @param flag
*/
public void setLastFlag(int flag) {
mLastFlag = flag;
}
/**
* 設置高度
*
* @param value
*/
public void setHeight(int value) {
mHeight = value;
}
/**
* 設置當前拖動位置
*
* @param position
*/
public void setCurrentDragPosition(int position) {
mDragPosition = position;
}
/**
* 從自身出現的動畫
*
* @param x
* @param y
* @return
*/
private Animation getFromSelfAnimation(int x, int y) {
TranslateAnimation translateAnimation = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.ABSOLUTE, x,
Animation.RELATIVE_TO_SELF, 0, Animation.ABSOLUTE, y);
translateAnimation
.setInterpolator(new AccelerateDecelerateInterpolator());
translateAnimation.setFillAfter(true);
translateAnimation.setDuration(100);
translateAnimation.setInterpolator(new AccelerateInterpolator());
return translateAnimation;
}
}
方法注釋很詳細,大家應該能弄明白,展示圖如下

AsyncTask - 基本原理 圖文剖析
最近用到了AsyncTask,這玩意每個寫android程序的都會用,可是不見得每個人都能用的好。如果想要用好,那麼首先勢必對基本原理有個大概了解。其實網上對這類問題的說
Android編程使用自定義View實現水波進度效果示例
本文實例講述了Android編程使用自定義View實現水波進度效果。分享給大家供大家參考,具體如下:首先上效果圖:簡介:1.自動適應屏幕大小;2.水波自動橫向滾動;3.各
【Android UI】ListView的使用和簡單優化
ListView是每個app中都要使用的,所以今天我來總結下ListView的使用和一些簡單的優化。先看下運行效果:一、創建數據庫為了模擬數據,這裡將數據保存數據庫中,順
Android 自定義Activity基類
我們在開發App的時候有時候碰到多個界面有一個共同點的時候,比如,都有相同的TitleBar,並且TitleBar可以設置顯示的文字。TitleBar上的點擊事件,如果給