Android Launcher 入门

Launcher(发射器),就是你经常看到主屏幕吧,其实它也是一个App,它加载着其它app的图标和名字,并通过意图打开i它们。

从本博客你可以从认识Launcher并且开发一个简单的Launcher,在你的模拟器上使用。

注意:

  1. 下面代码需要自己强烈建议手打,否则你只是复制了一个Demo。
  2. 如果你需要的只是看一下效果的话,请点击下载,转到GitHub上下载Demo,并查看。
  3. GitHub代码  需要把清单列表的注释解开

一、Launcher

1.什么是Launcher

安卓系统中的桌面启动器,安卓系统的桌面UI统称为Launcher

2. 定制Launcher

在许多国内手机都定制了自己的Launcher,并不予许用户使用其它Launcher。

尤其是在智能电视和车载上,都有自己的Launcher。

3.不同Launcher

Launcher也有许多不同版本,这章就不展开讲了,只是让你认识一下Launcher。

具体你可以看这里

二、开发一个简单Launcher

开发一个Launcher很简单,你只需要跟着我写下面的代码就可以得到一个自己的Launcher。

1.清单列表

在自己开发的APP的AndroidManifest中添加两句代码到自己的Activity里。

 <category android:name="android.intent.category.HOME"/>
 <category android:name="android.intent.category.DEFAULT"/>

启动模拟器,可以使用夜神或者AS中的模拟器,我使用过夜神5.0和AS中模拟器(5.0),都可以。一般国内真机都不行。

运行起来,就是一个Hellowrod,但是一旦返回到主界面,就会弹出询问使用什么Launcher。

这里是因为系统中有多个Launcher,所以询问,点击仅一次。你会发现效果是打开了这个只有HelloWrod的App,其实它已经是你的主屏幕了,接下来我们把它改造的像一点。

2.通过PackageManager获取应用


    private void getApps() {
        PackageManager packageManager = getPackageManager();
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        mMApps = packageManager.queryIntentActivities(intent, 0);
    }

3.建立视图预览

简单点,先创建一个RecycleView,把图标显示到上面,并添加点击事件,跳到个个应用。

在onBindViewHolder中写获取App图标和名字的代码,和点击事件的接口回调。


    @Override
    public void onBindViewHolder(@NonNull MyAppsAdapter.ViewHolder viewHolder, int i) {
        ResolveInfo resolveInfo = mMApps.get(i);
        Drawable drawable = resolveInfo.activityInfo.loadIcon(mContext.getPackageManager());
        CharSequence charSequence = resolveInfo.loadLabel(mContext.getPackageManager());
        viewHolder.mAppimg.setImageDrawable(drawable);
        viewHolder.mAppname.setText(charSequence);
        viewHolder.mAppimg.setOnClickListener(v -> {
            mMyAppsAdapterSetOnClickListener.OnClickListener(i);
        });
    }

大概效果就这样了

此时这个Launcher基本可以使用了,如果你嫌弃它不好看,我们可以加一个简单的背景。

在Styet里面添加一个背景

<style name="MyLauncher" parent="android:Theme.Wallpaper">
        <item name="android:windowNoTitle">true</item>
    </style>

在清单里配置

  <activity
                android:name=".MainActivity"
                android:theme="@style/MyLauncher"
                >

运行一下,效果如下:

如果崩溃了,请更改Activity继承关系

public class MainActivity extends Activity implements MyAppsAdapter.MyAppsAdapterSetOnClickListener {
   
   

三、附代码:

为了方便大家查看代码,在这我附出应用代码,免去下载代码的麻烦。

1.manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        package="com.example.mylauncher"
        >


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

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

</manifest>

2.MainActivty

1.MainActivty的代码

public class MainActivity extends Activity implements MyAppsAdapter.MyAppsAdapterSetOnClickListener {
    private String TAG = "MainActivity";
    private RecyclerView rl;
    private MyAppsAdapter mMyAppsAdapter;
    private List<ResolveInfo> mMApps;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        getApps();
        setData();
    }

    private void setData() {
        if (mMyAppsAdapter == null) {
            mMyAppsAdapter = new MyAppsAdapter(this, mMApps);
        }
        rl.setLayoutManager(new GridLayoutManager(this, 4));
        rl.setAdapter(mMyAppsAdapter);
        mMyAppsAdapter.setMyAppsAdapterSetOnClickListener(this);
    }

    private void getApps() {
        PackageManager packageManager = getPackageManager();
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        mMApps = packageManager.queryIntentActivities(intent, 0);
    }

    private void initView() {
        rl = findViewById(R.id.rl);
    }

    @Override
    public void OnClickListener(int i) {
        ResolveInfo resolveInfo = mMApps.get(i);
        String packageName = resolveInfo.activityInfo.packageName;
        String appName = resolveInfo.activityInfo.name;
        ComponentName componentName = new ComponentName(packageName, appName);
        Intent intent = new Intent();
        intent.setComponent(componentName);
        startActivity(intent);
    }
}

2.MainActivty的布局

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        >

    <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/rl"
            />

</android.support.constraint.ConstraintLayout>

3.MyAppsAdapter

1.MyAppsAdapter代码

package com.example.mylauncher;

import java.util.List;

import android.content.Context;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

class MyAppsAdapter extends RecyclerView.Adapter<MyAppsAdapter.ViewHolder> {
    private final Context mContext;
    private final List<ResolveInfo> mMApps;

    public MyAppsAdapter(MainActivity context, List<ResolveInfo> mApps) {
        mContext = context;
        mMApps = mApps;
    }

    @NonNull
    @Override
    public MyAppsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.recycler_view_item, null);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyAppsAdapter.ViewHolder viewHolder, int i) {
        ResolveInfo resolveInfo = mMApps.get(i);
        Drawable drawable = resolveInfo.activityInfo.loadIcon(mContext.getPackageManager());
        CharSequence charSequence = resolveInfo.loadLabel(mContext.getPackageManager());
        viewHolder.mAppimg.setImageDrawable(drawable);
        viewHolder.mAppname.setText(charSequence);
        viewHolder.mAppimg.setOnClickListener(v -> {
            mMyAppsAdapterSetOnClickListener.OnClickListener(i);
        });
    }

    @Override
    public int getItemCount() {
        return mMApps.size();
    }



    public class ViewHolder extends RecyclerView.ViewHolder {

        private final TextView mAppname;
        private final ImageView mAppimg;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            mAppimg = itemView.findViewById(R.id.appimg);
            mAppname = itemView.findViewById(R.id.appname);
        }
    }

    public MyAppsAdapterSetOnClickListener mMyAppsAdapterSetOnClickListener;

    public void setMyAppsAdapterSetOnClickListener(
            MyAppsAdapterSetOnClickListener myAppsAdapterSetOnClickListener) {
        mMyAppsAdapterSetOnClickListener = myAppsAdapterSetOnClickListener;
    }

    interface MyAppsAdapterSetOnClickListener {
        void OnClickListener(int i);
    }
}

xml

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >

    <ImageView
            android:id="@+id/appimg"
            android:layout_width="50dp"
            android:layout_height="50dp"
            tools:src="@tools:sample/avatars"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />

    <TextView
            android:id="@+id/appname"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:text="appname"
            app:layout_constraintTop_toBottomOf="@+id/appimg"
            app:layout_constraintStart_toStartOf="@+id/appimg"
            app:layout_constraintEnd_toEndOf="@+id/appimg"
            />

</android.support.constraint.ConstraintLayout>

3其它

1.style

    <style name="MyLauncher" parent="android:Theme.Wallpaper">
        <item name="android:windowNoTitle">true</item>
    </style>

2.依赖

 implementation 'com.android.support:recyclerview-v7:28.0.0'

猜你喜欢

转载自blog.csdn.net/qq_41346910/article/details/88868429