編輯:關於Android編程
[java]
public class OpenFolder {
public static String TAG = "OpenFolder";
/**
* folder animaltion execution time
*/
private static int ANIMALTION_TIME = 300;
private Context mContext;
private WindowManager mWindowManager;
private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
private OpenFolderContainer container;
private View mBackgroundView;
private View mFolderView;
private ImageView mTopView;
private ImageView mBottomView;
private int mUp_down;
private int[] mAnchorLocation = new int[2];
private int mSrceenwidth;
private int mSrceenheigh;
private int mFolderheigh;
private int offsety;
private int offsetyLast;
private boolean mIsOpened = false;
/**
* Listener that is called when this OpenFolder window is closed.
*/
public interface OnFolderClosedListener {
/**
* Called when this OpenFolder window is closed.
*/
public void onClosed();
}
private OnFolderClosedListener mOnFolderClosedListener;
/**
* the folder open Animation Listener
*/
private Animation.AnimationListener mOpenAnimationListener = new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
mIsOpened = true;
}
};
/**
* the folder colse Animation Listener
*/
private Animation.AnimationListener mClosedAnimationListener = new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
mWindowManager.removeView(container);
// 清空畫圖緩存區,否則獲取的還是原來的圖像
mBackgroundView.setDrawingCacheEnabled(false);
mIsOpened = false;
if (mOnFolderClosedListener != null) {
mOnFolderClosedListener.onClosed();
}
}
};
private static OpenFolder openFolder;
/**
* @param context
* @return
*/
public static OpenFolder getInstance(Context context) {
if (openFolder == null) {
openFolder = new OpenFolder(context);
}
return openFolder;
}
private OpenFolder(Context context) {
mContext = context;
mWindowManager = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
container = new OpenFolderContainer(mContext);
}
/**
*
* @param anchor
* folder展開參照容器
* @param backgroundView
* 當前用於顯示folder的頁面
* @param folderView
* folder頁面
* @param folderH
* folder頁面高度,dip
* @param up_down
* 0 為向上展開,否則向下展開
*/
public void openFolderView(View anchor, View backgroundView,
View folderView, int folderH, int up_down) {
mUp_down = up_down;
container.removeAllViews();
mBackgroundView = backgroundView;
mFolderheigh = dip2px(mContext, folderH);
mFolderView = folderView;
mSrceenwidth = backgroundView.getWidth();
mSrceenheigh = backgroundView.getHeight();
// 獲取參照控件的位置
anchor.getLocationInWindow(mAnchorLocation);
if (up_down == 0) {
offsety = mAnchorLocation[1];
} else {
offsety = anchor.getHeight() + mAnchorLocation[1];
}
prepareLayout();
startOpenAnimation();
}
/**
*
* @param offy
* folder在屏幕展開y軸位置 px
* @param backgroundView
* 當前用於顯示folder的頁面
* @param folderView
* folder頁面
* @param folderH
* folder頁面高度,dip
* @param up_down
* 0 為向上展開,否則向下展開
*/
public void openFolderView(int offy, View backgroundView, View folderView,
int folderH, int up_down) {
mUp_down = up_down;
container.removeAllViews();
mBackgroundView = backgroundView;
mFolderheigh = dip2px(mContext, folderH);
mFolderView = folderView;
mSrceenwidth = backgroundView.getWidth();
mSrceenheigh = backgroundView.getHeight();
offsety = offy;
prepareLayout();
startOpenAnimation();
}
private void prepareLayout() {
// add folderview
RelativeLayout.LayoutParams fp = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, mFolderheigh);
if (mUp_down == 0) {
fp.setMargins(0, offsety - mFolderheigh, 0, 0);
} else {
fp.setMargins(0, offsety, 0, 0);
}
container.addView(mFolderView, fp);
// 截當前view背景圖,用於分割 topview bottomview
mBackgroundView.setDrawingCacheEnabled(true);
Bitmap srceen = mBackgroundView.getDrawingCache();
// add topview
// 截圖控件以上部分
Bitmap top = Bitmap.createBitmap(srceen, 0, 0, mSrceenwidth, offsety);
mTopView = new ImageView(mContext);
mTopView.setId(1000);
mTopView.setBackgroundDrawable(new BitmapDrawable(mContext
.getResources(), top));
RelativeLayout.LayoutParams ft = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, offsety);
container.addView(mTopView, ft);
// add bottomview
// 截圖控件以下部分
Bitmap bottom = Bitmap.createBitmap(srceen, 0, offsety, mSrceenwidth,
mSrceenheigh - offsety);
mBottomView = new ImageView(mContext);
mBottomView.setBackgroundDrawable(new BitmapDrawable(mContext
.getResources(), bottom));
RelativeLayout.LayoutParams fb = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, mSrceenheigh - offsety);
fb.addRule(RelativeLayout.BELOW, 1000);
container.addView(mBottomView, fb);
mWindowManager.addView(container, createPopupLayout(mBackgroundView.getWindowToken()));
}
private void startOpenAnimation() {
// 展開動畫
if (mUp_down == 0) {
offsety = 0;
offsetyLast = 0 - mFolderheigh;
TranslateAnimation ta = new TranslateAnimation(0, 0, offsety,
offsetyLast);
ta.setInterpolator(new DecelerateInterpolator());
ta.setDuration(ANIMALTION_TIME);
ta.setFillAfter(true);
ta.setAnimationListener(mOpenAnimationListener);
mTopView.startAnimation(ta);
} else {
offsety = 0;
offsetyLast = offsety + mFolderheigh;
TranslateAnimation ta = new TranslateAnimation(0, 0, offsety,
offsetyLast);
ta.setInterpolator(new DecelerateInterpolator());
ta.setDuration(ANIMALTION_TIME);
ta.setFillAfter(true);
ta.setAnimationListener(mOpenAnimationListener);
mBottomView.startAnimation(ta);
}
}
private WindowManager.LayoutParams createPopupLayout(IBinder token) {
WindowManager.LayoutParams p = new WindowManager.LayoutParams();
p.gravity = Gravity.LEFT | Gravity.TOP;
p.width = mSrceenwidth;
p.height = mSrceenheigh;
p.format = PixelFormat.OPAQUE;
p.token = token;
p.type = mWindowLayoutType;
p.setTitle("OpenFolder:" + Integer.toHexString(hashCode()));
return p;
}
private static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
/**
* Sets the listener to be called when the openFolder is colsed.
*
* @param mOnClosedListener
*/
public void setmOnFolderClosedListener(OnFolderClosedListener onFolderClosedListener) {
this.mOnFolderClosedListener = onFolderClosedListener;
}
/**
* @return true if the folder is showing, false otherwise
*/
public boolean isOpened() {
return mIsOpened;
}
/**
* colse the folder
*/
private void dismiss() {
if (!mIsOpened) {
return;
}
//關閉動畫
TranslateAnimation tra = new TranslateAnimation(0, 0, offsetyLast,
offsety);
tra.setInterpolator(new DecelerateInterpolator());
tra.setDuration(ANIMALTION_TIME);
tra.setFillAfter(true);
tra.setAnimationListener(mClosedAnimationListener);
if (mUp_down == 0) {
mTopView.startAnimation(tra);
} else {
mBottomView.startAnimation(tra);
}
}
/**
*
* @author wangwenbin
*
*/
private class OpenFolderContainer extends RelativeLayout {
long lasttime = 0;
boolean isvalid = false;
public OpenFolderContainer(Context context) {
super(context);
}
/*
* (non-Javadoc)
*
* @see android.view.ViewGroup#dispatchKeyEvent(android.view.KeyEvent)
*/
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (getKeyDispatcherState() == null) {
return super.dispatchKeyEvent(event);
}
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getRepeatCount() == 0) {
KeyEvent.DispatcherState state = getKeyDispatcherState();
if (state != null) {
state.startTracking(event, this);
}
return true;
} else if (event.getAction() == KeyEvent.ACTION_UP) {
KeyEvent.DispatcherState state = getKeyDispatcherState();
if (state != null && state.isTracking(event)
&& !event.isCanceled()) {
dismiss();
return true;
}
}
return super.dispatchKeyEvent(event);
} else {
return super.dispatchKeyEvent(event);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int y = (int) event.getY();
if (System.currentTimeMillis() - lasttime > ANIMALTION_TIME) {
isvalid = true;
} else {
isvalid = false;
}
lasttime = System.currentTimeMillis();
if ((event.getAction() == MotionEvent.ACTION_DOWN) && isvalid
&& (y < offsety || y > offsetyLast)) {
dismiss();
return true;
} else {
return super.onTouchEvent(event);
}
}
}
}
調用此自定義插件代碼
[java]
<pre name="code" class="java">public class MainActivity extends Activity implements View.OnClickListener {
Button btn1;
Button btn2;
OpenFolder openFolder;
View folderview;
/*
* (non-Javadoc)
*
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn1 = (Button) findViewById(R.id.button1);
btn1.setOnClickListener(this);
btn2 = (Button) findViewById(R.id.button2);
btn2.setOnClickListener(this);
openFolder = OpenFolder.getInstance(this);
LayoutInflater inflater = LayoutInflater.from(this);
folderview = inflater.inflate(R.layout.folderview, null);
}
/*
* (non-Javadoc)
*
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
@Override
public void onClick(View v) {
if (v.equals(btn1)) {
openFolder.openFolderView(btn1, getWindow().getDecorView(),
folderview, 80, 1);
openFolder.setmOnFolderClosedListener(new OpenFolder.OnFolderClosedListener() {
@Override
public void onClosed() {
Toast.makeText(getBaseContext(),
"close folder btn1", Toast.LENGTH_SHORT)
.show();
}
});
} else if (v.equals(btn2)) {
openFolder.openFolderView(btn2, getWindow().getDecorView(),
folderview, 80, 0);
openFolder.setmOnFolderClosedListener(new OpenFolder.OnFolderClosedListener() {
@Override
public void onClosed() {
Toast.makeText(getBaseContext(),
"close folder btn2", Toast.LENGTH_SHORT)
.show();
}
});
}
}</pre><pre name="code" class="java">}</pre><pre name="code" class="java"></pre><pre name="code" class="java"></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
畫圖設計到圖片的格式,有空可以看看圖片資源各種格式。了解一下圖片格式,對學習有用的。而且我面試別人的時候也很喜歡問這個問題,哈哈。先看個圖。直接看代碼吧,注釋很詳細了。a
原文鏈接:http://code.tutsplus.com/tutorials/dependency-injection-with-dagger-2-on-android
Interpolator屬性是Animation類的一個XML屬性,所以alpha、scale、rotate、translate、set都會繼承得到這個屬性。Interp
最近由於項目需要,寶寶好久沒搞Android啦,又是因為項目需要,現在繼續弄Android,哎,說多了都是淚呀,別的不用多說,先搞一個登錄界面練練手,登錄界面可以說是An