當(dāng)我們?cè)谑褂玫腶pp的時(shí)候,如果需要實(shí)時(shí)觀測(cè)到某個(gè)功能的實(shí)時(shí)進(jìn)度并且不影響其他的操作的時(shí)候或者不影響使用其他應(yīng)用的時(shí)候,系統(tǒng)級(jí)的懸浮球是個(gè)非常不錯(cuò)的選擇。
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名注冊(cè)、虛擬空間、營銷軟件、網(wǎng)站建設(shè)、唐縣網(wǎng)站維護(hù)、網(wǎng)站推廣。
public class QueueUpFloatService extends Service {
/**
* 啟動(dòng)服務(wù)并傳值
*
* @param activity 啟動(dòng)服務(wù)的activity
* @param modeBean 數(shù)據(jù)對(duì)象
*/
public static void launchService(Activity activity, ModeBean modeBean) {
try {
Intent intent =new Intent(activity, QueueUpFloatService.class);
? ? Bundle bundle =new Bundle();
? ? bundle.putSerializable(KEY_MODEL, modeBean);
? ? intent.putExtras(bundle);
? ? activity.startService(intent);
}catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
@Override
public void onCreate() {
super.onCreate();
//加一點(diǎn)簡單的動(dòng)畫?
buttonScale = (ScaleAnimation) AnimationUtils.loadAnimation(this, R.anim.anim_float);
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
layoutParams =new WindowManager.LayoutParams();
if (Build.VERSION.SDK_INT = Build.VERSION_CODES.O) {
layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
}else {
layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
}
layoutParams.format = PixelFormat.RGBA_8888;
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | ????????????WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
layoutParams.width = ScreenUtils.dp2px(66);
layoutParams.height = ScreenUtils.dp2px(66);
layoutParams.x = ScreenUtils.getRealWidth() - ScreenUtils.dp2px(60);
layoutParams.y = ScreenUtils.deviceHeight() *2 /3;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
ModeBean modeBean = (ModeBean) intent.getExtras().getSerializable(KEY_MODEL);
LayoutInflater layoutInflater = LayoutInflater.from(this);
floatView = layoutInflater.inflate(R.layout.view_float, null);
RelativeLayout rlFloatParent =floatView.findViewById(R.id.rl_float_parent);
rlFloatParent.startAnimation(buttonScale);
TextView tvIndex =floatView.findViewById(R.id.tv_queue_index);
tvIndex.setText(modeBean.title);
floatView.findViewById(R.id.iv_close_float).setOnClickListener(v - stopSelf());
//修改懸浮球的滑動(dòng)實(shí)現(xiàn)
floatView.setOnTouchListener(new FloatingOnTouchListener());
windowManager.addView(floatView, layoutParams);
return super.onStartCommand(intent, flags, startId);
}
private class FloatingOnTouchListenerimplements View.OnTouchListener {
private int x;
private int y;
private long downTime;
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downTime = System.currentTimeMillis();
? ? ? ? ? ? ????????x = (int) event.getRawX();
? ? ? ? ? ????????? y = (int) event.getRawY();
break;
? ? ? ????? case MotionEvent.ACTION_MOVE:
int nowX = (int) event.getRawX();
? ? ????????? ? ? ? int nowY = (int) event.getRawY();
? ? ? ????????? ? ? int movedX = nowX -x;
? ? ? ? ????????? ? int movedY = nowY -y;
? ? ? ? ????????? ? x = nowX;
? ? ? ? ? ????????? y = nowY;
? ? ? ? ? ????????? layoutParams.x =layoutParams.x + movedX;
? ? ? ? ? ? ????????layoutParams.y =layoutParams.y + movedY;
? ? ? ? ? ? ? ? ? ? windowManager.updateViewLayout(view, layoutParams);
break;
? ? ? ????? case MotionEvent.ACTION_UP:
/* *
* 這里根據(jù)手指按下和抬起的時(shí)間差來判斷點(diǎn)擊事件還是滑動(dòng)事件
* */
? ? ? ? ????????? ? if ((System.currentTimeMillis() -downTime) 200) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? //檢測(cè)應(yīng)用在前臺(tái)還是后臺(tái)
if (AppUtils.isAppIsInBackground()) {
AppUtils.moveToFront(CloseActivityUtils.activityList.get(CloseActivityUtils.activityList.size() -1).getClass());
? ? ? ? ? ? ? ????????????? } else {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //檢測(cè)棧頂是否為SecondActivity 不是就打開SecondActivity
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (!CloseActivityUtils.activityList.get(CloseActivityUtils.activityList.size() -1)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ????????????????.getClass().getSimpleName().contains("SecondActivity")) {
? ? ? ? ? ? ? ? ? ? ? ? ? ????????? SecondActivity.launchActivity(CloseActivityUtils.activityList.get(CloseActivityUtils.activityList.size() -1));
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? }
}
break;
? ? ? ? default:
break;
? ? }
? ?return false;
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (null ==floatView) {
return;
? ? ? ? ? ?}
windowManager.removeView(floatView);
? ? ? ? windowManager=null;
}
如果您想關(guān)閉懸浮導(dǎo)航,進(jìn)入設(shè)置 系統(tǒng)和更新 系統(tǒng)導(dǎo)航方式 更多 或設(shè)置 系統(tǒng)和更新 系統(tǒng)導(dǎo)航方式 懸浮導(dǎo)航 (取決于您的機(jī)型),關(guān)閉懸浮導(dǎo)航開關(guān)。
android懸浮按鈕(Floating action button)的兩種實(shí)現(xiàn)方法
最近android中有很多新的設(shè)計(jì)規(guī)范被引入,最流行的莫過于被稱作Promoted Actions的設(shè)計(jì)了,Promoted Actions是指一種操作按鈕,它不是放在actionbar中,而是直接在可見的UI布局中(當(dāng)然這里的UI指的是setContentView所管轄的范圍)。因此它更容易在代碼中被獲取到(試想如果你要在actionbar中獲取一個(gè)菜單按鈕是不是很難?),Promoted Actions往往主要用于一個(gè)界面的主要操作,比如在email的郵件列表界面,promoted action可以用于接受一個(gè)新郵件。promoted action在外觀上其實(shí)就是一個(gè)懸浮按鈕,更常見的是漂浮在界面上的圓形按鈕,一般我直接將promoted action稱作懸浮按鈕,英文名稱Float Action Button?簡稱(FAB,不是FBI哈)。
float?action?button是android l中的產(chǎn)物,但是我們也可以在更早的版本中實(shí)現(xiàn)。假設(shè)我這里有一個(gè)列表界面,我想使用floataction?button代表添加新元素的功能,界面如下:
要實(shí)現(xiàn)float?action?button可以有多種方法,一種只適合android L,另外一種適合任意版本。
用ImageButton實(shí)現(xiàn)
這種方式其實(shí)是在ImageButton的屬性中使用了android L才有的一些特性:
ImageButton
android:layout_width="56dp"
android:layout_height="56dp"
android:src="@drawable/plus"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
android:tint="@android:color/white"
android:id="@+id/fab"
android:elevation="1dp"
android:background="@drawable/ripple"
android:stateListAnimator="@anim/fab_anim"
/
仔細(xì)一點(diǎn),你會(huì)發(fā)現(xiàn)我們將這個(gè)ImageButton放到了布局的右下角,為了實(shí)現(xiàn)float?action?button應(yīng)該具備的效果,需要考慮以下幾個(gè)方面:
·Background
·Shadow
·Animation
背景上我們使用ripple drawable來增強(qiáng)吸引力。注意上面的xml代碼中我們將background設(shè)置成了@drawable/ripple?,ripple drawable的定義如下:
ripple xmlns:android="" android:color="?android:colorControlHighlight"
item
shape android:shape="oval"
solid android:color="?android:colorAccent" /
/shape
/item
/ripple
既然是懸浮按鈕,那就需要強(qiáng)調(diào)維度上面的感覺,當(dāng)按鈕被按下的時(shí)候,按鈕的陰影需要擴(kuò)大,并且這個(gè)過程是漸變的,我們使用屬性動(dòng)畫去改變translatioz。
selector xmlns:android=""
item
android:state_enabled="true"
android:state_pressed="true"
objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="translationZ"
android:valueFrom="@dimen/start_z"
android:valueTo="@dimen/end_z"
android:valueType="floatType" /
/item
item
objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="translationZ"
android:valueFrom="@dimen/end_z"
android:valueTo="@dimen/start_z"
android:valueType="floatType" /
/item
/selector
使用自定義控件的方式實(shí)現(xiàn)懸浮按鈕
這種方式不依賴于android L,而是碼代碼。
首先定義一個(gè)這樣的類:
public class CustomFAB extends ImageButton {
...
}
然后是讀取一些自定義的屬性(假設(shè)你了解styleable的用法)
private void init(AttributeSet attrSet) {
Resources.Theme theme = ctx.getTheme();
TypedArray arr = theme.obtainStyledAttributes(attrSet, R.styleable.FAB, 0, 0);
try {
setBgColor(arr.getColor(R.styleable.FAB_bg_color, Color.BLUE));
setBgColorPressed(arr.getColor(R.styleable.FAB_bg_color_pressed, Color.GRAY));
StateListDrawable sld = new StateListDrawable();
sld.addState(new int[] {android.R.attr.state_pressed}, createButton(bgColorPressed));
sld.addState(new int[] {}, createButton(bgColor));
setBackground(sld);
}
catch(Throwable t) {}
finally {
arr.recycle();
}
}
在xml中我們需要加入如下代碼,一般是在attr.xml文件中。
?xml version="1.0" encoding="utf-8"?
resources
declare-styleable name="FAB"
!-- Background color --
attr name="bg_color" format="color|reference"/
attr name="bg_color_pressed" format="color|reference"/
/declare-styleable
/resources
使用StateListDrawable來實(shí)現(xiàn)不同狀態(tài)下的背景
private Drawable createButton(int color) {
OvalShape oShape = new OvalShape();
ShapeDrawable sd = new ShapeDrawable(oShape);
setWillNotDraw(false);
sd.getPaint().setColor(color);
OvalShape oShape1 = new OvalShape();
ShapeDrawable sd1 = new ShapeDrawable(oShape);
sd1.setShaderFactory(new ShapeDrawable.ShaderFactory() {
@Override
public Shader resize(int width, int height) {
LinearGradient lg = new LinearGradient(0,0,0, height,
new int[] {
Color.WHITE,
Color.GRAY,
Color.DKGRAY,
Color.BLACK
}, null, Shader.TileMode.REPEAT);
return lg;
}
});
LayerDrawable ld = new LayerDrawable(new Drawable[] { sd1, sd });
ld.setLayerInset(0, 5, 5, 0, 0);
ld.setLayerInset(1, 0, 0, 5, 5);
return ld;
}
最后將控件放xml中:
RelativeLayout xmlns:android=""
xmlns:tools=""
xmlns:custom=""
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MyActivity"
...
com.survivingwithandroid.fab.CustomFAB
android:layout_width="56dp"
android:layout_height="56dp"
android:src="@android:drawable/ic_input_add"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
custom:bg_color="@color/light_blue"
android:tint="@android:color/white"
/
/RelativeLayout
網(wǎng)頁名稱:android懸浮按鈕,android懸浮按鈕彈出與隱藏
網(wǎng)站鏈接:http://aaarwkj.com/article44/dssjche.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、手機(jī)網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、做網(wǎng)站、網(wǎng)站收錄、電子商務(wù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)