آموزش ساخت Widget شناور آیکون برنامه در اندروید

در این مقاله قصد داریم که یک ویجت درست کنیم که این ابزار یک آیکون شناور که بر روی صفحه است می توان حرکت داد و آن را از روی صفحه به صفحه ی اصلی یا هر جایی که شما می خواهید می توانید حرکت دهید.

آموزش ساخت Widget شناور آیکون برنامه در اندروید

ابتدا باید مجوز دسترسی به این سرویس را در قسمت manifest خود قرار دهید:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

حالا باید عکس مورد نظر را در پوشه ی مربوطه قرار دهید:

حالا باید قطعه کد کلاس را اضافه نمایید:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.net.Uri;
import android.os.Build;
import android.view.View;
import android.content.Intent;
import android.provider.Settings;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    public static final int SYSTEM_ALERT_WINDOW_PERMISSION = 7;
    Button button ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        button = (Button)findViewById(R.id.buttonShow);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {

            RuntimePermissionForUser();
        }

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {

                    startService(new Intent(MainActivity.this, FloatingWidgetShowService.class));

                    finish();

                } else if (Settings.canDrawOverlays(MainActivity.this)) {

                    startService(new Intent(MainActivity.this, FloatingWidgetShowService.class));

                    finish();

                } else {
                    RuntimePermissionForUser();

                    Toast.makeText(MainActivity.this, "System Alert Window Permission Is Required For Floating Widget.", Toast.LENGTH_LONG).show();
                }

            }
        });

    }

    public void RuntimePermissionForUser() {

        Intent PermissionIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + getPackageName()));

        startActivityForResult(PermissionIntent, SYSTEM_ALERT_WINDOW_PERMISSION);
    }
}

در قسمت بعدی باید لایه ی مورد نظر را اضافه کنید:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.android_examples.floatingwidget_android_examplescom.MainActivity"
    android:layout_margin="10dp">

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Click Here To Show Floating Widget"
        android:id="@+id/buttonShow"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

کلاس سرویس را برای شناور شدن به صورت زیر می باشد:

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.graphics.PixelFormat;
import android.view.LayoutInflater;
import android.view.WindowManager;
import android.view.MotionEvent;
import android.view.View;


public class FloatingWidgetShowService extends Service{


    WindowManager windowManager;
    View floatingView, collapsedView, expandedView;
    WindowManager.LayoutParams params ;

    public FloatingWidgetShowService() {
    }

    @Override
    public IBinder onBind(Intent intent) {

        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        floatingView = LayoutInflater.from(this).inflate(R.layout.floating_widget_layout, null);

        params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);

        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

        windowManager.addView(floatingView, params);

        expandedView = floatingView.findViewById(R.id.Layout_Expended);

        collapsedView = floatingView.findViewById(R.id.Layout_Collapsed);

        floatingView.findViewById(R.id.Widget_Close_Icon).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                stopSelf();

            }
        });

        expandedView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                collapsedView.setVisibility(View.VISIBLE);
                expandedView.setVisibility(View.GONE);

            }
        });

        floatingView.findViewById(R.id.MainParentRelativeLayout).setOnTouchListener(new View.OnTouchListener() {
            int X_Axis, Y_Axis;
            float TouchX, TouchY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {

                    case MotionEvent.ACTION_DOWN:
                        X_Axis = params.x;
                        Y_Axis = params.y;
                        TouchX = event.getRawX();
                        TouchY = event.getRawY();
                        return true;

                    case MotionEvent.ACTION_UP:

                        collapsedView.setVisibility(View.GONE);
                        expandedView.setVisibility(View.VISIBLE);
                        return true;

                    case MotionEvent.ACTION_MOVE:

                        params.x = X_Axis + (int) (event.getRawX() - TouchX);
                        params.y = Y_Axis + (int) (event.getRawY() - TouchY);
                        windowManager.updateViewLayout(floatingView, params);
                        return true;
                }
                return false;
            }
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (floatingView != null) windowManager.removeView(floatingView);
    }

}

لایه مورد نظر به صورت زیر می باشد:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">


    <RelativeLayout
        android:id="@+id/MainParentRelativeLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:ignore="UselessParent">

        <!-- This layout is the Collapsed layout -->
        <RelativeLayout
            android:id="@+id/Layout_Collapsed"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:visibility="visible">

            <ImageView
                android:id="@+id/Logo_Icon"
                android:layout_width="72dp"
                android:layout_height="72dp"
                android:layout_marginTop="10dp"
                android:src="@drawable/mobile_icon" />

            <ImageView
                android:id="@+id/Widget_Close_Icon"
                android:layout_width="23dp"
                android:layout_height="23dp"
                android:layout_marginLeft="50dp"
                android:src="@drawable/close_icon" />
        </RelativeLayout>

        <!-- This layout is expended layout-->

        <LinearLayout
            android:id="@+id/Layout_Expended"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#FFF3E0"
            android:orientation="horizontal"
            android:padding="8dp"
            android:visibility="gone">

            <ImageView
                android:id="@+id/WebsiteLogoIcon"
                android:layout_width="80dp"
                android:layout_height="80dp"
                android:src="@drawable/mobile_icon"
                tools:ignore="ContentDescription" />

            <LinearLayout
                android:id="@+id/LinearLayout_2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingLeft="5dp"
                    android:paddingRight="5dp"
                    android:paddingTop="5dp"
                    android:text="Android-Examples"
                    android:textAlignment="center"
                    android:textSize="23dp"
                    android:textColor="#000"
                    android:textStyle="bold" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="www.android-examples.com"
                    android:textAlignment="center"
                    android:textSize="18dp"
                    android:textColor="#000"
                    android:textStyle="bold" />
            </LinearLayout>

        </LinearLayout>
    </RelativeLayout>
</FrameLayout>

کد کامل اندروید منیفست باید یک سرویس را اضافه کرد که به صورت زیر خواهد بود:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android_examples.floatingwidget_android_examplescom">

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".FloatingWidgetShowService"
            android:enabled="true"
            android:exported="false" />

    </application>

</manifest>

خروجی کار:

فایل های ضمیمه