此例中父布局为RelativeLayout,布局,所以ImageButton控件可以在此布局中悬浮于其他view之上。

详细见代码(此例不含拖动后的位置记忆,下一篇文章会提到)。

 (10.30更新:我还是把位置保存在此处一并说了吧,见文尾。)

XML文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/home"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff">
    <FrameLayout
        android:id="@+id/realtabcontent"
        android:layout_alignParentTop="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <com.anxpp.phyg.utils.view.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="@drawable/x_back_tab_home">
    </com.anxpp.phyg.utils.view.FragmentTabHost>
    <ImageButton
        android:id="@+id/btn_suspension"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:scaleType="centerCrop"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:src="@drawable/sus_cart"
        android:background="#00000000"
        android:text="@string/hello_world" />
</RelativeLayout>

java代码:

 (HomeActivity.java)

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        //绘制区
        Rect drawRect = new Rect();
        getWindow().findViewById(Window.ID_ANDROID_CONTENT).getDrawingRect(drawRect);
        //应用区
        Rect appRect = new Rect();
        getWindow().getDecorView().getWindowVisibleDisplayFrame(appRect);
        int statusBarHeight = appRect.top-drawRect.top;
        findViewById(R.id.home_main_top).setPadding(0, statusBarHeight, 0, 0);
        //设置悬浮窗
        new SuspensionImgBtn((ViewGroup)findViewById(R.id.home),
                (ImageButton)findViewById(R.id.btn_suspension)).setSusCart(new SuspensionImgBtn.SusClick() {
            @Override
            public void onTouch() {
                Toast.makeText(HomeActivity.this,"点击购物车图标",Toast.LENGTH_SHORT).show();
            }
        });
    }

 SuspensionImgBtn.java

package com.anxpp.phyg.utils.view;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
/**
 * Created by anxpp on 2015/10/29.
 * 悬浮按钮
 * 在RelativeLayout布局中的ImageButton控件
 */
public class SuspensionImgBtn {
    //可拖动控件
    ImageButton _view;  //可拖动布局
    ViewGroup _root;    //父布局
    int oldX;           //上次点击的点    用来判断是点击还是move
    int oldY;           //上次点击的点
    private int _xDelta;
    private int _yDelta;
    //构造传入父布局和imgButton
    public SuspensionImgBtn(ViewGroup root,ImageButton view){
        this._root = root;
        this._view = view;
    }
    //处理按钮
    public void setSusCart(final SusClick sus){
        int width = _view.getMeasuredWidth();
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width, width);
        layoutParams.leftMargin = 50;
        layoutParams.topMargin = 50;
        layoutParams.bottomMargin = -250;
        layoutParams.rightMargin = -250;
        _view.setLayoutParams(layoutParams);
        _view.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent event) {
                final int X = (int) event.getRawX();
                final int Y = (int) event.getRawY();
                switch (event.getAction() & MotionEvent.ACTION_MASK) {
                    case MotionEvent.ACTION_DOWN:
                        RelativeLayout.LayoutParams lParams =
                                (RelativeLayout.LayoutParams) view.getLayoutParams();
                        _xDelta = X - lParams.leftMargin;
                        _yDelta = Y - lParams.topMargin;
                        oldX = (int) event.getRawX();
                        oldY = (int) event.getRawY();
                        break;
                    case MotionEvent.ACTION_UP:
                        //此时判断为点击
                        if(oldX == (int) event.getRawX()&&oldY == (int) event.getRawY())
                            sus.onTouch();
                        break;
                    case MotionEvent.ACTION_POINTER_DOWN:
                        break;
                    case MotionEvent.ACTION_POINTER_UP:
                        break;
                    case MotionEvent.ACTION_MOVE:
                        RelativeLayout.LayoutParams layoutParams =
                                (RelativeLayout.LayoutParams) view.getLayoutParams();
                        layoutParams.leftMargin = X - _xDelta;
                        layoutParams.topMargin = Y - _yDelta;
                        layoutParams.rightMargin = -250;
                        layoutParams.bottomMargin = -250;
                        view.setLayoutParams(layoutParams);
                        break;
                }
                _root.invalidate();
                return true;
            }
        });
    }
    public interface SusClick{
        void onTouch();
    }
}

位置记忆使用SharedPreference实现:

MySharedPrerences.java 请见Android数据的四种存储方式一 —— SharedPreference