Android Recyclerview for Installed Apps with Checkbox

android recyclerview

One of the most common reasons that you would want to use the android recyclerview is if you want to show a list of some sort. In this example, let’s take a look at how you can use the android recyclerview to show a list of installed apps on your device. Within each item, we will also include a checkbox. Here’s what it will look like:

android recyclerview apps

Layout

Let’s first take care of creating the layout files. Here is my layout file for the main activity (activity_main.xml). I am using a FrameLayout, with the Recyclerview and Floating Action Button. The floating action button is not necessary for this tutorial.

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

<FrameLayout 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="match_parent">


    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycleView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:layout_editor_absoluteX="8dp"
        tools:layout_editor_absoluteY="8dp" />


    <android.support.design.widget.FloatingActionButton
        android:id="@+id/sharebutton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="16dp"
        android:clickable="true"
        app:elevation="6dp"
        app:fabSize="normal"

        app:srcCompat="@android:drawable/ic_menu_share" />


</FrameLayout>

Next, let’s take care of the layout for each individual item in the list. I am calling this main_line_view.xml. It contains the following contents:

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

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="8dp">

            <ImageView
                android:id="@+id/packageImage"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginRight="5dp"
                android:layout_marginTop="6dp"
                android:src="@mipmap/ic_launcher" />

            <TextView
                android:id="@+id/Apk_Name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="4dp"
                android:layout_marginTop="6dp"
                android:layout_toEndOf="@id/packageImage"
                android:layout_toRightOf="@id/packageImage"
                android:textColor="#000" />

            <TextView
                android:id="@+id/Apk_Package_Name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/Apk_Name"
                android:layout_marginLeft="4dp"
                android:layout_toEndOf="@id/packageImage"
                android:layout_toRightOf="@id/packageImage"
                android:textColor="#795548"

                />

            <CheckBox
                android:id="@+id/appSelect"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_centerVertical="true" />
        </RelativeLayout>

    </LinearLayout>


</RelativeLayout>

Viewing Installed Apps

Now let’s work on getting the list of apps installed on your device. The only important line of code that you will need is the following:

List<ApplicationInfo> packages = mContext.getPackageManager().getInstalledApplications(0);

However, I also want to grab app name and icon. To keep things easy and re-usable, I created a class called AppManager and added the following contents:

public class AppsManager {
    private Context mContext;
    private AppInfo appInfo;
    private ArrayList<AppInfo> myApps;

    public AppsManager(Context c) {
        mContext = c;
        myApps = new ArrayList<AppInfo>();
    }

    public ArrayList<AppInfo> getApps() {
        loadApps();
        return myApps;
    }


    private void loadApps() {

        List<ApplicationInfo> packages = mContext.getPackageManager().getInstalledApplications(0);
        for (ApplicationInfo packageInfo : packages) {
            AppInfo newApp = new AppInfo();
            newApp.setAppName(getApplicationLabelByPackageName(packageInfo.packageName));
            newApp.setAppPackage(packageInfo.packageName);
            newApp.setAppIcon(getAppIconByPackageName(packageInfo.packageName));
            myApps.add(newApp);
        }

        Collections.sort(myApps, new Comparator<AppInfo>() {
            @Override
            public int compare(AppInfo s1, AppInfo s2) {
                return s1.getAppName().compareToIgnoreCase(s2.getAppName());

            }
        });

    }


    // Custom method to get application icon by package name
    private Drawable getAppIconByPackageName(String packageName) {
        Drawable icon;
        try {
            icon = mContext.getPackageManager().getApplicationIcon(packageName);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            // Get a default icon
            icon = ContextCompat.getDrawable(mContext, R.drawable.ic_launcher_background);
        }
        return icon;
    }

    // Custom method to get application label by package name
    private String getApplicationLabelByPackageName(String packageName) {
        PackageManager packageManager = mContext.getPackageManager();
        ApplicationInfo applicationInfo;
        String label = "Unknown";
        try {
            applicationInfo = packageManager.getApplicationInfo(packageName, 0);
            if (applicationInfo != null) {
                label = (String) packageManager.getApplicationLabel(applicationInfo);
            }

        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return label;
    }
}

The first function called loadApps gets the list of installed applications on the device. You will notice that I created my own custom class called AppInfo. This is because I wanted to store particular values and info from each class. Here is what the class AppInfo looks like:

public class AppInfo {
    private String appName;
    private String appPackage;
    private Drawable appIcon;
    private boolean isSelected;

    public String getAppPackage() {
        return appPackage;
    }

    public void setAppPackage(String appPackage) {
        this.appPackage = appPackage;
    }

    public Drawable getAppIcon() {
        return appIcon;
    }

    public void setAppIcon(Drawable appIcon) {
        this.appIcon = appIcon;
    }

    public boolean isSelected() {
        return isSelected;
    }

    public void setSelected(boolean selected) {
        isSelected = selected;
    }

    public String getAppName() {
        return appName;
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }
}

So loadApps essentially saves a list of type AppInfo. I also implement a custom sort method that will sort the apps by their app name. You can then grab the list using the getApps method.

View Adapter

Now it’s time to implement a view adapter. If you worked with listviews in the pass, then this will look very familiar. Essentially, a view adapter controls how the recyclerview will show the view. It also maps all of our items from the main_line_view.xml to functions in the adapter. So here’s what the adapter looks like:

public class InstalledAppsAdapter extends RecyclerView.Adapter<InstalledAppsAdapter.ViewHolder> {

    private Context mContext;
    private ArrayList<AppInfo> mDataSet;

    public InstalledAppsAdapter(Context context, ArrayList<AppInfo> list) {
        mContext = context;
        mDataSet = list;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        public TextView mTextViewLabel;
        public TextView mTextViewPackage;
        public ImageView mImageViewIcon;
        public CheckBox mAppSelect;
        public RelativeLayout mItem;

        public ViewHolder(View v) {
            super(v);
            // Get the widgets reference from custom layout
            mTextViewLabel = (TextView) v.findViewById(R.id.Apk_Name);
            mTextViewPackage = (TextView) v.findViewById(R.id.Apk_Package_Name);
            mImageViewIcon = (ImageView) v.findViewById(R.id.packageImage);
            mAppSelect = (CheckBox) v.findViewById(R.id.appSelect);
            mItem = (RelativeLayout) v.findViewById(R.id.item);
        }

    }

    @Override
    public InstalledAppsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(mContext).inflate(R.layout.main_line_view, parent, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {

        // Get the current package name
        final String packageName = mDataSet.get(position).getAppPackage();

        // Get the current app icon
        Drawable icon = mDataSet.get(position).getAppIcon();

        // Get the current app label
        String label = mDataSet.get(position).getAppName();

        // Set the current app label
        holder.mTextViewLabel.setText(label);

        // Set the current app package name
        holder.mTextViewPackage.setText(packageName);

        // Set the current app icon
        holder.mImageViewIcon.setImageDrawable(icon);

        holder.mAppSelect.setChecked(mDataSet.get(position).isSelected());

        holder.mItem.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mDataSet.get(position).setSelected(!mDataSet.get(position).isSelected());
                InstalledAppsAdapter.this.notifyDataSetChanged();
            }
        });


    }

    @Override
    public int getItemCount() {
        // Count the installed apps
        return mDataSet.size();
    }

}

The only thing I want to point out if how I am handling the checkbox click. You will see the I implemented a listener that wraps the entire item. When it’s clicked, I set the selected boolean to the opposite of what it was. Finally, I used the line notifyDataSetChanged so that the recyclerview will refresh the list.

Main Activity

Finally, we can finish it up in our main activity by using the following lines:

public class MainActivity extends AppCompatActivity {

    private RelativeLayout mRelativeLayout;

    private RecyclerView mRecyclerView;
    private RecyclerView.LayoutManager mLayoutManager;
    private RecyclerView.Adapter mAdapter;
    private ArrayList<AppInfo> installedApps;
    private FloatingActionButton shareButton;
    private AppsManager appManager;
    private final String baseURL = "http://192.168.50.48/post.php";

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

        installedApps = new ArrayList<AppInfo>();
        mRecyclerView = (RecyclerView) findViewById(R.id.recycleView);
        shareButton = (FloatingActionButton) findViewById(R.id.sharebutton);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(layoutManager);
        appManager = new AppsManager(this);
        installedApps = appManager.getApps();

        // Initialize a new adapter for RecyclerView
        mAdapter = new InstalledAppsAdapter(
                getApplicationContext(),
                installedApps
        );


        mRecyclerView.setAdapter(mAdapter);
      
    }
}

That’s it! You can now have an android app that will display a list of installed apps using the recyclerview with a checkbox next to each item.