Android系統(tǒng)開發(fā)全攻略(二)
只貼出抽屜組件的源碼,其他源文件與基礎(chǔ)篇的一樣:
?。踛ava] view plaincopyprint?
《span style=“font-family:Comic Sans MS;font-size:18px;”》public class Panel extends LinearLayout implements GestureDetector.OnGestureListener{
public interface PanelClosedEvent {
void onPanelClosed(View panel);
}
public interface PanelOpenedEvent {
void onPanelOpened(View panel);
}
private final static int HANDLE_WIDTH=30;
private final static int MOVE_WIDTH=20;
private Button btnHandler;
private LinearLayout panelContainer;
private int mRightMargin=0;
private Context mContext;
private GestureDetector mGestureDetector;
private boolean mIsScrolling=false;
private float mScrollX;
private PanelClosedEvent panelClosedEvent=null;
private PanelOpenedEvent panelOpenedEvent=null;
public Panel(Context context,View otherView,int width,int height) {
super(context);
this.mContext=context;
//定義手勢識別
mGestureDetector = new GestureDetector(mContext,this);
mGestureDetector.setIsLongpressEnabled(false);
//改變Panel附近組件的屬性
LayoutParams otherLP=(LayoutParams) otherView.getLayoutParams();
otherLP.weight=1;
otherView.setLayoutParams(otherLP);
//設(shè)置Panel本身的屬性
LayoutParams lp=new LayoutParams(width, height);
lp.rightMargin=-lp.width+HANDLE_WIDTH;
mRightMargin=Math.abs(lp.rightMargin);
this.setLayoutParams(lp);
this.setOrientation(LinearLayout.HORIZONTAL);
//設(shè)置Handler的屬性
btnHandler=new Button(context);
btnHandler.setLayoutParams(new LayoutParams(HANDLE_WIDTH,height));
//btnHandler.setOnClickListener(handlerClickEvent);
btnHandler.setOnTouchListener(handlerTouchEvent);
this.addView(btnHandler);
//設(shè)置Container的屬性
panelContainer=new LinearLayout(context);
panelContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
this.addView(panelContainer);
}
private View.OnTouchListener handlerTouchEvent=new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_UP //onScroll時(shí)的ACTION_UP
mIsScrolling==true)
{
LayoutParams lp=(LayoutParams) Panel.this.getLayoutParams();
if (lp.rightMargin 》= (-mRightMargin/2)) {//往左超過一半
new AsynMove().execute(new Integer[] { MOVE_WIDTH });// 正數(shù)展開
}
else if (lp.rightMargin 《 (-mRightMargin/2)) {//往右拖拉
new AsynMove().execute(new Integer[] { -MOVE_WIDTH });// 負(fù)數(shù)收縮
}
}
return mGestureDetector.onTouchEvent(event);
}
};
/**
* 定義收縮時(shí)的回調(diào)函數(shù)
* @param event
*/
public void setPanelClosedEvent(PanelClosedEvent event)
{
this.panelClosedEvent=event;
}
/**
* 定義展開時(shí)的回調(diào)函數(shù)
* @param event
*/
public void setPanelOpenedEvent(PanelOpenedEvent event)
{
this.panelOpenedEvent=event;
}
/**
* 把View放在Panel的Container
* @param v
*/
public void fillPanelContainer(View v)
{
panelContainer.addView(v);
}
/**
* 異步移動(dòng)Panel
* @author hellogv
*/
class AsynMove extends AsyncTask《Integer, Integer, Void》 {
@Override
protected Void doInBackground(Integer.。。 params) {
int times;
if (mRightMargin % Math.abs(params[0]) == 0)// 整除
times = mRightMargin / Math.abs(params[0]);
else
// 有余數(shù)
times = mRightMargin / Math.abs(params[0]) + 1;
for (int i = 0; i 《 times; i++) {
publishProgress(params);
try {
Thread.sleep(Math.abs(params[0]));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer.。。 params) {
LayoutParams lp = (LayoutParams) Panel.this.getLayoutParams();
if (params[0] 《 0)
lp.rightMargin = Math.max(lp.rightMargin + params[0],
(-mRightMargin));
else
lp.rightMargin = Math.min(lp.rightMargin + params[0], 0);
if(lp.rightMargin==0 panelOpenedEvent!=null){//展開之后
panelOpenedEvent.onPanelOpened(Panel.this);//調(diào)用OPEN回調(diào)函數(shù)
}
else if(lp.rightMargin==-(mRightMargin) panelClosedEvent!=null){//收縮之后
panelClosedEvent.onPanelClosed(Panel.this);//調(diào)用CLOSE回調(diào)函數(shù)
}
Panel.this.setLayoutParams(lp);
}
}
@Override
public boolean onDown(MotionEvent e) {
mScrollX=0;
mIsScrolling=false;
return false;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
LayoutParams lp = (LayoutParams) Panel.this.getLayoutParams();
if (lp.rightMargin 《 0)// CLOSE的狀態(tài)
new AsynMove().execute(new Integer[] { MOVE_WIDTH });// 正數(shù)展開
else if (lp.rightMargin 》= 0)// OPEN的狀態(tài)
new AsynMove().execute(new Integer[] { -MOVE_WIDTH });// 負(fù)數(shù)收縮
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
mIsScrolling=true;
mScrollX+=distanceX;
LayoutParams lp=(LayoutParams) Panel.this.getLayoutParams();
if (lp.rightMargin 《 -1 mScrollX 》 0) {//往左拖拉
lp.rightMargin = Math.min((lp.rightMargin + (int) mScrollX),0);
Panel.this.setLayoutParams(lp);
Log.e(“onScroll”,lp.rightMargin+“”);
}
else if (lp.rightMargin 》 -(mRightMargin) mScrollX 《 0) {//往右拖拉
lp.rightMargin = Math.max((lp.rightMargin + (int) mScrollX),-mRightMargin);
Panel.this.setLayoutParams(lp);
}
if(lp.rightMargin==0 panelOpenedEvent!=null){//展開之后
panelOpenedEvent.onPanelOpened(Panel.this);//調(diào)用OPEN回調(diào)函數(shù)
}
else if(lp.rightMargin==-(mRightMargin) panelClosedEvent!=null){//收縮之后
panelClosedEvent.onPanelClosed(Panel.this);//調(diào)用CLOSE回調(diào)函數(shù)
}
Log.e(“onScroll”,lp.rightMargin+“”);
return false;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {return false;}
@Override
public void onLongPress(MotionEvent e) {}
@Override
public void onShowPress(MotionEvent e) {}
}
《/span》
三、Android智能手機(jī)藍(lán)牙通信功能開發(fā):BluetoothChat例程分析
1. 概述
Bluetooth 是幾乎現(xiàn)在每部手機(jī)標(biāo)準(zhǔn)配備的功能,多用于耳機(jī) mic 等設(shè)備與手機(jī)的連接,除此之外,還可以多部手機(jī)之間建立 bluetooth 通信,本文就通過 SDK 中帶的一個(gè)聊天室的例程,來介紹一下 Android 上的 Bluetooth 的開發(fā)。
在 Android1.x 的時(shí)候,相關(guān) API 非常不完善,還不能簡單的使用 Bluetooth 開發(fā),有一個(gè)開源項(xiàng)目可以幫助程序員使用、開發(fā)藍(lán)牙,支持直接方法 bluetooth 協(xié)議棧。在 Android2 以后,框架提供了一些官方 API 來進(jìn)行藍(lán)牙的通信,但目前的程序也比較不完善。本文主要討論 Android2 后的 Bluetooth 通信的 API 使用方法。
首先看聊天室的效果圖:
2. Bluetooth 通信 API 介紹
2.1. Bluetooth 通信過程
2.2. Bluetooth API 的主要方法
BluetoothAdapter 類
BluetoothAdapter.getDefaultAdapter() :得到本地默認(rèn)的 BluetoothAdapter ,若返回為 null 則表示本地不支持藍(lán)牙;
isDiscovering() :返回設(shè)備是否正在發(fā)現(xiàn)周圍藍(lán)牙設(shè)備;
cancelDiscovery() :取消正在發(fā)現(xiàn)遠(yuǎn)程藍(lán)牙設(shè)備的過程;
startDiscovery() :開始發(fā)現(xiàn)過程;
getScanMode() :得到本地藍(lán)牙設(shè)備的 Scan Mode ;
getBondedDevices() :得到已配對的設(shè)備;
isEnabled() :藍(lán)牙功能是否啟用。
評論