編輯:關於Android編程
先上效果圖:
之前用手機QQ時,一直很覺得這個窗口提示挺不錯的,今天將它大概地實現了一遍。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPsrXz8jKx6O6zOHKvrSwv9q1xMj9vcfPwrHqyse/ydLUuMSx5M671sO1xKOsyLu687Swv9rW0NPQuty24NChtcRpdGVto6xpdGVtsbu147v3yrG74c/Uyr6z9rK7zay1xNHVyaujrDwvcD4NCjxwPs2syrHI/b3Hz8Kx6rXE0dXJq9Kyy+bXxbjEseShozwvcD4NCjxwPsi7uvPKx6O6zOHKvrSwv9q1xGl0ZW3Dx7vhuPm+3bSryOu1xNf4serKtc/Wz/LJz8/Uyr678s/yz8LP1Mq+oaM8L3A+DQo8aDIgaWQ9"一對tipview定義一些成員變量">一、對TipView定義一些成員變量
// 一些狀態變量
private static final int STATUS_DOWN = 1;
private static final int STATUS_UP = 2;
// 初始窗口的Item顯示在上方
private int mStatus = STATUS_UP;
// Item之間的分隔線的顏色
private int mSeparateLineColor ;
// 窗口邊上兩個方塊的邊角半徑大小
private int mCorner = dip2px(6);
private Paint mPaint; // 畫方塊和文字的畫筆
private Paint doPaint; // 畫三角下標的畫筆
private Path mPath; // 繪制的路徑
private int mBorderMargin = dip2px(5); // 提示窗口與屏幕(根布局)的最小距離
private int mItemWidth = dip2px(50); // 窗口Item的寬度
private int mItemHeight = dip2px(48); // 窗口Item的高度
private int mTriangleTop = dip2px(50); // 三角下標的頂點
private int mHalfTriangleWidth = dip2px(6); // 三角小標的半寬
private int mItemBorder; // 三角小標與窗口Item的臨界
private int realLeft; // 窗口的left值
private List mItemList = new ArrayList<>(); // 存儲每個Item的信息
private List mItemRectList = new ArrayList<>(); // 存儲每個方塊的信息
private OnItemClickListener onItemClickListener; // Item點擊接口
private int choose = -1; // 是否有Item被按下,是為Item的序號,否為-1
// 外界傳入的點擊坐標x、y
private int x;
private int y;
二、TipView的初始化
TipView的構造方法:
public TipView(Context context, ViewGroup rootView,int x,int y,List mItemList) {
super(context);
this.x = x; // 設置傳入過來的x軸坐標
this.y = y; // 設置傳入過來的y軸坐標
// x和y決定了三角下標的位置
initPaint(); // 初始化畫筆
setTipItemList(mItemList); // 初始化Item集合,並對Item的字符串長度進行處理
//【當字符串過長時,使用後端省略處理:“xxx...”】
addView(rootView); // 將TipView實例添加到傳入的rootView中。
// 注意:rootView需要FrameLayout/RelativeLayout或其子類實例
initView(); // 根據傳入的點擊坐標x、y進行狀態判斷和最左位置的處理
}
initView()的具體實現:主要對臨界情況的一些值得處理
private void initView() {
// 獲取屏幕寬度
int mScreenWidth = getResources().getDisplayMetrics().widthPixels;
// 當點擊事件的縱坐標y比較小時(點擊的位置比較上面)
if (y/2 mScreenWidth) {
// 跑出屏幕右邊的話,則減去溢出的寬度,再減去距離值
realLeft -= realLeft + (mItemWidth*mItemList.size())-mScreenWidth+mBorderMargin;
// 防止三角下標與方塊分離
if(x+mCorner>=realLeft+mItemWidth*mItemList.size())
x = realLeft+mItemWidth*mItemList.size()-mCorner*2;
}
// 沒有對窗口左右邊都超出的情況做處理,大家有沒有好的解決方案?
}
三、TipView的繪制
首先繪制圖層為透明,再根據判斷得來的狀態繪制窗口。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawBackground(canvas);
switch (mStatus) {
case STATUS_DOWN:
drawItemDown(canvas);
break;
case STATUS_UP:
drawItemUp(canvas);
break;
default:
break;
}
}
具體繪制各個窗口方塊的代碼太長不便貼出,可參考源碼及其注釋。
大致的流程就是
a. 繪制最左方塊、最右方塊和中間方塊
b. 根據方塊是否被點擊而更換不同的顏色來繪制方塊
c. 繪制分隔線
四、TipView中的Item點擊事件的監聽
設計一個監聽器接口:
public interface OnItemClickListener {
// 設計兩個參數
void onItemClick(String name,int position);
void dismiss();
}
覆寫TipView的onTouchEvent方法:
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
for (int i = 0; i < mItemRectList.size(); i++) {
if (onItemClickListener != null && isPointInRect(new PointF(event.getX(), event.getY()), mItemRectList.get(i))) {
// 被按下時,choose值為當前方塊Item序號
choose = i;
// 更新視圖
invalidate(mItemRectList.get(i));
}
}
return true;
case MotionEvent.ACTION_UP:
for (int i = 0; i < mItemRectList.size(); i++) {
if (onItemClickListener != null && isPointInRect(new PointF(event.getX(), event.getY()), mItemRectList.get(i))) {
// 觸發方法,傳入兩個參數
onItemClickListener.onItemClick(mItemList.get(i).getTitle(),i);
choose = -1;
}
}
if (onItemClickListener != null) {
onItemClickListener.dismiss(); // 觸發方法
}
removeView(); // 移除TipView
return true;
}
return true;
}
五、以Build模式為設計模式:
public static class Builder {
// TipView中一些重要的成員變量
private OnItemClickListener onItemClickListener;
private Context mContext;
private ViewGroup mRootView;
private List mTipItemList = new ArrayList<>();
private int mSeparateLineColor = Color.WHITE;
private int x ,y;
public Builder(Context context, ViewGroup rootView,int x,int y) {
mContext = context;
mRootView = rootView;
this.x = x;
this.y = y;
}
public Builder addItem(TipItem tipItem) {
mTipItemList.add(tipItem);
return this;
}
public Builder addItems(List list) {
mTipItemList.addAll(list);
return this;
}
public Builder setSeparateLineColor(int color) {
mSeparateLineColor = color;
return this;
}
public Builder setOnItemClickListener(OnItemClickListener onItemClickListener){
this.onItemClickListener = onItemClickListener;
return this;
}
// 創建TipView實例
public TipView create() {
TipView flipShare = new TipView(mContext, mRootView,x,y,mTipItemList);
flipShare.setOnItemClickListener(onItemClickListener);
flipShare.setSeparateLineColor(mSeparateLineColor);
return flipShare;
}
}
六、使用示例:
創建TipView實例時,需要傳入控件被點擊或長按時的位置坐標。
使用注意:傳給rootView的參數需要FrameLayout / RelativeLayout或其子類實例,這樣TipView對象才可以懸浮地顯示出來。
public class MainActivity extends AppCompatActivity {
private Button button0;
private RelativeLayout rl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button0 = (Button) findViewById(R.id.button0);
rl = (RelativeLayout) findViewById(R.id.activity_main);
button0.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = 0;int y = 0;
if(event.getAction()==MotionEvent.ACTION_UP){
// 獲取點擊位置
x= (int) event.getX();y = (int) event.getY();
Log.i("zz",x+" "+y);
// 傳入視圖上的坐標
TipView share = new TipView.Builder(MainActivity.this,rl,x+v.getLeft(),y+v.getTop())
.addItem(new TipItem("復制復制"))
.addItem(new TipItem("粘貼"))
.addItem(new TipItem("刪除"))
.addItem(new TipItem("收藏"))
.addItem(new TipItem("轉發"))
.addItem(new TipItem("更多"))
.setOnItemClickListener(new TipView.OnItemClickListener() {
@Override
public void onItemClick(String str,int a) {
Toast.makeText(MainActivity.this,str,Toast.LENGTH_SHORT).show();
}
@Override
public void dismiss() {
}
})
.create();
}
return true;
}
});
}
}
效果圖Demo:Github
參考:
https://github.com/JeasonWong/FlipShare
一般情況下,Android系統安裝apk會出現一個安裝界面,用戶可以點擊確定或者取消來進行apk的安裝。 但在實際的項目需求中,有一種需求,就是希望apk在後台安裝(不出
當我們彈出一個Dialog時候,如果這個Dialog需要輸入數據,然後確定後又需要關閉輸入法,一般系統的hide,跟show方法總會有各種問題,最霸道的解決方法就是寫一個
這周的工作對Android項目多分辨率自適應進行調整。故對這方面知識進行不斷的嘗試學習。Android項目剛開始做的時候一定養成編程習慣,所有資源調用放在value中。統
android程序和java程序的區別Android程序不像Java程序一樣,隨便創建一個類,寫個main()方法就能跑了,而是要有一個完整的Android工程環境,在這