Iqra Iqra - 20 days ago 7
Android Question

How to Add ListView Items where checkbox is selected to separate ArrayList?

I am developing an app in which I want to display all the installed applications in listView. I am succeed in doing so. Each item in my ListView contains name of application and checkbox. I want whenever user presses button all the Application names where checkbox is IsSelected() should be stored in seperate ArrayList.I have tried so many things but nothing works. My code is:

main_activity.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="@+id/container"
android:layout_height="match_parent"
tools:context="com.example.pc.fkidshell.Teen5Activity">

<ListView
android:id="@+id/list"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="1"/>
<Button
android:id="@+id/btn_add2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginBottom="20dp"
android:text="Add Selected Apps"
android:width="170dp"
android:layout_weight="2"
android:layout_alignParentBottom="true"
android:layout_gravity="center_horizontal" />
</FrameLayout>


inflator.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center"
android:layout_gravity="center"
android:orientation="horizontal"
android:weightSum="2" >
<TextView
android:id="@+id/a"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:textColor="#000"
android:layout_gravity="center"
android:gravity="center"
android:layout_weight="1.7" />

<CheckBox
android:id="@+id/b"
android:layout_width="0dp"
android:layout_gravity="center"
android:gravity="center"
android:layout_weight="0.3"
android:layout_height="wrap_content" />

</LinearLayout>


Datamodel.java

public class Datamodel {
public String appname = "";
private boolean selected;

public String getAppname() {
return appname;
}

public void setAppname(String appname) {
this.appname = appname;
}

public boolean isSelected() {
return selected;
}

public void setSelected(boolean isChecked) {
this.selected = isChecked;
}

}


Adapter.java: (in checkbox listener i am using statement "MyApplication.setMyapps(ss);" to assign application name to my global class (MyApplication) variable ArrayList myapps)

public class Adapter extends BaseAdapter {
Context _ctx;
LayoutInflater inflater;
public ArrayList<Datamodel> data;

public Adapter(Context c, ArrayList<Datamodel> _arraylist) {
this._ctx = c;
this.data = _arraylist;
}

@Override
public int getCount() {
return data.size();
}

@Override
public Object getItem(int position) {
return position;
}

@Override
public long getItemId(int position) {
return 0;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
inflater = (LayoutInflater) _ctx.getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.inflator, parent, false);
final CheckBox checks = (CheckBox) itemView.findViewById(R.id.b);
final TextView _setappname = (TextView) itemView.findViewById(R.id.a);
checks.setChecked(data.get(position).isSelected());

Datamodel obj = data.get(position);
_setappname.setText(obj.getAppname());
checks.setTag(position);

checks.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
int getPosition = (Integer) buttonView.getTag();
Datamodel _obj = data.get(getPosition);
data.get(position).setSelected(isChecked);
String ss = _obj.getAppname();
System.out.println("pos is" + getPosition);
MyApplication.setMyapps(ss);
}
});
return itemView;
}
}


Mainactivity.java:

public class Teen5Activity extends Activity
{
private ListView list;
ArrayList<Datamodel> res;
Adapter _adapter;

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

list = (ListView) findViewById(R.id.list);
List<PackageInfo> _myapps = getPackageManager().getInstalledPackages(0); //all the list of apps pacakage info stores in _myapps
res = new ArrayList<Datamodel>(); //new arraylist that contains appname and checkboxes status
for (int i = 0; i < _myapps.size(); i++)
{
PackageInfo p = _myapps.get(i);

Datamodel _model = new Datamodel();
_model.setAppname(p.applicationInfo.loadLabel(getPackageManager()).toString());
res.add(_model);
System.out.println("ajajajja" + res.size() + res.get(i).getAppname());
}
_adapter = new Adapter(getApplicationContext(), res);
_adapter.notifyDataSetChanged();
list.setAdapter(_adapter);
Button addbtn=(Button) findViewById(R.id.btn_add2);
addbtn.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if((MyApplication.getMyapps())==null)
{
Toast.makeText(getApplicationContext(), "Nothing to ADD!", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(), "Successfully Added your Apps!", Toast.LENGTH_LONG).show();
}

}
});
}
}


MyApplication.java:

public class MyApplication extends Application
{
private static ArrayList<String> myapps=null;
public static void setMyapps(String logo)
{
myapps.add(logo);
}
public static ArrayList<String> getMyapps()
{
return myapps;
}

}

Answer

Following mistakes I could find in your code:

1) You need to initialize your MyApplication class's myApps arraylist.If you try to call setMyApps without initializing your arrayList, you will get a null-pointer exception. You need also need a remove method to dynamically update your checked-apps list.

public class MyApplication extends Application
{
private static ArrayList<String> myapps= new ArrayList<String>();//Create an instance of the list, don't keep it as null

public static void setMyapps(String logo)
{
    myapps.add(logo);
}
public static ArrayList<String> getMyapps()
{
    return myapps;
}
public static void removeApp(String appName)
{
     myapps.remove(appName);
}

}

2) You need to add it to your list, only if it is checked, not for the false state. So whenever, you access the list, the elements that are present refer to the checked applications.Also, you need to remove the app name from the list in the event of a check and a later uncheck case.

 checks.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
    {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
        {
            int getPosition = (Integer) buttonView.getTag();
            Datamodel _obj = data.get(getPosition);
            data.get(position).setSelected(isChecked);
            String ss = _obj.getAppname();
            System.out.println("pos is" + getPosition);
            if(isChecked) //Only if the app is checked
                MyApplication.setMyapps(ss);
            else if(MyApplication.getMyApps().contains(ss))
                MyApplication.removeApp(ss);
        }
    });

3)I am not sure why you are extending the MyApplication class from Application here, if your objective is to store the app names.. a simple string arraylist would have sufficed.

4) It would be better to track the applications through their package name, instead of app name, as the package name is a more unique property to the app.

Comments