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:
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 **F****loating 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>
Build Grade
In your build Gradle (of the module: App), make sure that you include the following:
implementation 'com.android.support:recyclerview-v7:26.1.0'
implementation 'com.android.support:design:26.1.0'
Update the version to match the SDK that you are targeting.
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.