If you want to make your listview element dynamic, for instance with image & package name, create your object class :
public class AppIcon {
private Drawable mDrawable;
private String mPackageName;
public AppIcon(Drawable drawable, String packageName) {
this.mDrawable = drawable;
this.mPackageName = packageName;
}
public Drawable getmDrawable() {
return mDrawable;
}
public String getmPackageName() {
return mPackageName;
}
}
Create the following custom RecyclerView adapter :
public class ImageArrayAdapter extends RecyclerView.Adapter<ImageArrayAdapter.ViewHolder> {
/**
* list of devices
*/
private List<AppIcon> imageList = new ArrayList<>();
private Context mContext;
private IViewHolderClickListener mListener;
public ImageArrayAdapter(Context context, List<AppIcon> objects, IViewHolderClickListener listener) {
this.mContext = context;
this.imageList = objects;
this.mListener = listener;
}
@Override
public ImageArrayAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View inflater = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_item, parent, false);
return new ViewHolder(inflater, mListener);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
AppIcon item = imageList.get(position);
holder.image.setImageDrawable(item.getmDrawable());
holder.packageName.setText(item.getmPackageName());
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return imageList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ImageView image;
public TextView packageName;
public IViewHolderClickListener mListener;
/**
* ViewHolder
*
* @param v
* @param listener
*/
public ViewHolder(View v, IViewHolderClickListener listener) {
super(v);
mListener = listener;
image = (ImageView) v.findViewById(R.id.image);
packageName = (TextView) v.findViewById(R.id.package_name);
v.setOnClickListener(this);
}
@Override
public void onClick(View v) {
mListener.onClick(v);
}
}
}
This is better to use RecyclerView especially if you deal with a large list of image.
build.gradle :
compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.android.support:recyclerview-v7:+'
You can see that ViewHolder holds all your nested fields in your listview items and will dispatch click event too with :
public interface IViewHolderClickListener {
void onClick(View v);
}
In your activity, create your adapter and set it as adapter's RecyclerView. Also, initialize your adapter with list of image :
public class DescriptionActivity extends Activity {
private RecyclerView imageRecyclerView = null;
private ImageArrayAdapter imageAdapter = null;
private SwipeRefreshLayout mSwipeRefreshLayout;
private ArrayList<AppIcon> imageList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
//setup recyclerview
imageRecyclerView = (RecyclerView) findViewById(R.id.image_list);
imageList = new ArrayList<>();
try {
Drawable icon = getPackageManager().getApplicationIcon(getPackageName());
imageList.add(new AppIcon(icon, getPackageName()));
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
imageAdapter = new ImageArrayAdapter(DescriptionActivity.this, imageList, new IViewHolderClickListener() {
@Override
public void onClick(View v) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(DescriptionActivity.this, "click on item detected", Toast.LENGTH_SHORT).show();
}
});
}
});
//set layout manager
imageRecyclerView.setLayoutManager(new GridLayoutManager(this, 1, LinearLayoutManager.VERTICAL, false));
imageRecyclerView.setAdapter(imageAdapter);
//setup swipe refresh
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiperefresh);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
runOnUiThread(new Runnable() {
@Override
public void run() {
//refresh list here
imageAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
}
});
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
activity.xml looks like :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/image_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>
and listview_item.xml which contain the layout for each your image/package name listview item :
<ImageView
android:id="@+id/image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:scaleType="center"
android:layout_weight="0.5" />
<TextView
android:id="@+id/package_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:fontFamily="sans-serif"
android:textSize="18sp" />
Also, note that optionnaly I added a SwipeRefreshLayout to swipe refresh your listview in a material style