Search code examples
androidlistviewonitemclicklisteneronitemclick

OnClickItem with unknown number of items Android


I have an array of objects. In my listview, I pass only the name of those objects but when someone clicks on any of them, I want a new window to pop up and to see the extra information from my items. Can I do that somehow?

This is how my list activity looks like:

public class ListItemsActivity extends ListActivity {
    String[] mTestArray;
    ListView listView;
    private static final String TAG = "ListActivity";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "Trying to create the list activitye");
        super.onCreate(savedInstanceState);
        ArrayAdapter<String> adapter;

        mTestArray = getResources().getStringArray(R.array.sections);
        ArrayList<Sweet> sweets = getSweets(mTestArray);
        ArrayList<String> result = getSweetsNames(mTestArray);
        Log.d(TAG, mTestArray.toString());

        adapter = new ArrayAdapter<String>(
                this,
                R.layout.activity_list_items,
                result;
        setListAdapter(adapter);
    }

    public void onListItemClick(ListView parent, View v, int position, long id) {
        parent.setItemChecked(position, parent.isItemChecked(position));

        Toast.makeText(this, "You have selected " + mTestArray[position],
                Toast.LENGTH_SHORT).show();
    }

So this is ok, it shows me a lsit of names. And when I click on them it jsut tells me on a small popup thing that I've selected it. What I want is actually to open a new window and show all the information from my items. Is that possible? How would I go around to do it?

The only way I found is to do something like this:

public void onItemClick(AdapterView<?> parent, View view,
  int position, long id) {
   switch( position ) {
     case 0:  Intent newActivity = new Intent(this, i1.class);     
              startActivity(newActivity);
              break;
     case 1:  Intent newActivity = new Intent(this, i2.class);     
              startActivity(newActivity);
              break;
     case 2:  Intent newActivity = new Intent(this, i3.class);     
              startActivity(newActivity);
              break;
     case 3:  Intent newActivity = new Intent(this, i4.class);     
              startActivity(newActivity);
              break;
     case 4:  Intent newActivity = new Intent(this, i5.class);     
              startActivity(newActivity);
              break;
    }
}

But it's a bad approach for these reasons: 1) I have an unknown number of elements 2)I dont have 1000 activities for each item, I want 1 general window that would depend on some integer position.

Can I do it this way?


Solution

  • If you are getting position of the item from listView, then I think you can get the information about same item by the use of Adapter.

    Codes that you can try:

    1. Make a xml that your list view items would have:

    This can include any types of items and items would be seen in the list view as you would want to show it. I am making an xml named list_items_view.xml and including just a text view in the listview.

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:id="@+id/nameInList"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="26dp"
            android:padding="7dp"/>
    
    </RelativeLayout>
    
    1. Make a class that would include the items that you want to bind with each list-items:

    Here I am binding each list items with it's description, price, and callories (You can change that according to your need), and make constructor and getter-setter method for each one.Name of the class is ListDetailsClass:

    public class ListDetailsClass {
    
        String price,name, description,calories;
    
        public String getPrice() {
            return price;
        }
    
        public void setPrice(String price) {
            this.price = price;
        }
    
        public ListDetailsClass(String price, String name, String description, String calories) {
            this.price = price;
            this.name = name;
            this.description = description;
            this.calories = calories;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    
        public String getCalories() {
            return calories;
        }
    
        public void setCalories(String calories) {
            this.calories = calories;
        }
    }
    
    1. Make an adapter that could adapt the properties of the xml and the class in one single item:

    Here I have made an adapter class that extends BaseAdapter and implemented it's methods according to use of my purpose.Name of the class is adapterForLV:

    public class adapterForLV extends BaseAdapter {
    
        ArrayList<ListDetailsClass> itemsInList;
        Context mContext;
    
        LayoutInflater inflater;
    
        public Context getmContext() {
            return mContext;
        }
    
        public void setmContext(Context mContext) {
            this.mContext = mContext;
        }
    
        public ArrayList<ListDetailsClass> getItemsInList() {
            return itemsInList;
        }
    
        public void setItemsInList(ArrayList<ListDetailsClass> itemsInList) {
            this.itemsInList = itemsInList;
        }
    
        public adapterForLV(ArrayList<ListDetailsClass> itemsInList, Context mContext) {
            this.itemsInList = itemsInList;
            this.mContext = mContext;
        }
    
        @Override
        public int getCount() {
            return itemsInList.size();
        }
    
        @Override
        public Object getItem(int position) {
            return itemsInList.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
    
            if(inflater == null){
                inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            }
            if(convertView == null){
                convertView = inflater.inflate(R.layout.list_items_view,null);
            }
    
            TextView nameOfItem = (TextView) convertView.findViewById(R.id.nameInList);
    
            ListDetailsClass items = itemsInList.get(position);
    
            String name = items.getName();
    
            nameOfItem.setText(items.getName());
    
            return convertView;
        }
    }
    
    1. Finally implement adapter in your main activity so as to include the list items with bound data:(Name of the activity is MainActivity)

      ListView listView;
      
      ArrayList<ListDetailsClass> list = new ArrayList<>();
      
      adapterForLV customAdapter;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
      
          listView = (ListView) findViewById(R.id.lv) ;
      
      //Adapted the list form with customAdapter
      
          customAdapter = new adapterForLV(list,this);
      
      //Set the listview to the customAdapter
      
          listView.setAdapter(customAdapter);
      
      //Made two new objects of the ListDetaisClass to add data in the listview 
      
          ListDetailsClass newData = new ListDetailsClass("3$","abc","description","543 cal");
          ListDetailsClass newData2 = new ListDetailsClass("35.3$","item name","description about item","callories about it");
      
      //Added data to the list
      
          list.add(newData);
          list.add(newData2);
      
      
      //Listview item click listener implementation
          listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
          @Override
          public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      
              String name = customAdapter.getItemsInList().get(position).getName();
              String description = customAdapter.getItemsInList().get(position).getDescription();
              String price = customAdapter.getItemsInList().get(position).getPrice();
              String calories = customAdapter.getItemsInList().get(position).getCalories();
      
      
      //Intent to pass the data of the list item to next activity
      
              Intent i = new Intent(getApplicationContext(),Main2Activity.class);
              i.putExtra("Item_Name",name);
              i.putExtra("Item_Desc",description);
              i.putExtra("Item_Price",price);
              i.putExtra("Item_cal",calories);
              startActivity(i);
      
          }
          });
      
      }
      
    2. Getting the data to show in the form according to our use in the new activity:

    Here you have to define a new xml for the new activity so that data could be shown in the form we want.

    Main2Activity:

    //defined textViews to show my data
    TextView itemName,itemDescription,itemPrice,itemCal;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    
        itemName = (TextView) findViewById(R.id.ItemName);
        itemDescription = (TextView) findViewById(R.id.ItemDescr);
        itemCal = (TextView) findViewById(R.id.ItemCal);
        itemPrice = (TextView) findViewById(R.id.ItemPrice);
    
    //Getting data from oldActivity i.e. MainActivity
        Intent i = getIntent();
    
    //Setting data to textViews
        itemName.setText("Name: "+i.getStringExtra("Item_Name"));
        itemDescription.setText("Description: "+i.getStringExtra("Item_Desc"));
        itemPrice.setText("Price: "+i.getStringExtra("Item_Price"));
        itemCal.setText("Calories: "+i.getStringExtra("Item_cal"));
    
    
    }
    

    Screenshots after implementation:

    1. Listview

    Listview

    1. Item details in new activity

    item details

    Hope this help you!