Get the ID of checkbox from custom adapter in android? - java

I have a Custom ArrayList as follows.
public class sendivitesadapter extends ArrayAdapter<Item>{
private Context context;
private ArrayList<Item> items;
private qrusers qrusers;
private LayoutInflater vi;
public sendivitesadapter(Context context,ArrayList<Item> items) {
super(context, 0,items);
this.context= context;
this.qrusers =(qrusers) context;
this.items = items;
vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return super.getCount();
}
#Override
public Item getItem(int position) {
// TODO Auto-generated method stub
return super.getItem(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
final Item i = items.get(position);
if (i != null) {
if(i.isSection()){
SectionItem si = (SectionItem)i;
v = vi.inflate(R.layout.checkboxlist, null);
v.setOnClickListener(null);
v.setOnLongClickListener(null);
v.setLongClickable(false);
final TextView sectionView = (TextView) v.findViewById(R.id.list_item_section_text);
sectionView.setText(si.getTitle());
}else{
sendItem ei = (sendItem)i;
v = vi.inflate(R.layout.checkboxlist, null);
final TextView title = (TextView)v.findViewById(R.id.contactname);
final TextView subtitle = (TextView)v.findViewById(R.id.companyname);
final CheckBox checkBox=(CheckBox)v.findViewById(R.id.checboxlist);
if (title != null)
title.setText(ei.contactname);
if(subtitle != null)
subtitle.setText(ei.companyname);
}
}
return v;
}
and it looks like following image.
My java file is as follows.
#Override
protected void onPostExecute(String result) {
JSONArray jarray;
try {
jarray= new JSONArray(result);
name= new String[jarray.length()];
company=new String[jarray.length()];
for (int i=0;i<jarray.length();i++){
JSONObject jobj = jarray.getJSONObject(i);
name[i]= jobj.getString("Name");
company[i]=jobj.getString("Company");
items.add(new sendItem(name[i], company[i], checkBox));
adapter = new sendivitesadapter(qrusers.this,items);
listView.setAdapter(adapter);
Now I get the names from webservice which I am diplaying it in a listview as shown above.
With every name I get a USerID. So my question is whenever the user checks the checkbox in any sequence and click on add user I want the UserID of the checked checkboxes in array. How can I achieve this?

Sounds like it's a good candidate for View.setTag(). You could set the tag on each CheckBox to the id of the user [when you create it, or assign the Name and Company values]. Then in an OnClick or OnChecked type event, you can call view.getTag() to retrieve the id of the currently checked box.

You need to use OnCheckedChangeListener to get the cheched CheckBox ID. This SO will help you- How to handle onCheckedChangeListener for a RadioGroup in a custom ListView adapter . You need to modify the onCheckedChangeListener according to your need.

In your adapter set the position in check box like
checkBox.setTag(position);
And as i think you have to add checked user on click of Add User button. So on click of that button write following code.
public void onClick(View v) {
// TODO Auto-generated method stub
String categoryArray = "";
String[] categoryId;
if(v == AddUser){
int count = 0;
for(int i = 0; i < listViewRightSlideMenu.getChildCount(); i ++){
RelativeLayout relativeLayout = (RelativeLayout)listViewRightSlideMenu.getChildAt(i);
CheckBox ch = (CheckBox) relativeLayout.findViewById(R.id.checkBoxCategory); //use same id of check box which you used in adapter
if(ch.isChecked()){
count++;
categoryArray = categoryArray+ch.getTag()+",";
}
}
if(categoryArray.length() > 0) {
categoryArray = categoryArray.substring(0, categoryArray.length() - 1);
String[] array = categoryArray.split(",");
categoryId = new String[array.length];
for(int i = 0; i< array.length; i++) {
categoryId[i] = listCategory.get(Integer.valueOf(array[i])).getId();
}
for(int i = 0; i < categoryId.length; i++){
String a = categoryId[i];
System.out.println("category id is: "+a);
}
System.out.println("array position: "+categoryId);
}
}

Related

How to preselected checkbox show when again arraylist open in android

First I am selecting some array item using checkbox and displaying it in second activity. After that I am again opening my first activity of ArrayList but my checkbox selection clears.
Below is my code
public class Occassion extends AppCompatActivity implements View.OnClickListener,AdapterView.OnItemClickListener {
ListView listView_occassion;
ArrayAdapter<String> adapterOccassion;
Button mButtonOccassionNext;
int position;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_occassion);
listView_occassion = (ListView) findViewById(R.id.occassion_listview);
mButtonOccassionNext = (Button) findViewById(R.id.btn_occassion_next);
listView_occassion.setOnItemClickListener(this);
String[] Occassion = getResources().getStringArray(R.array.occassion_array);
adapterOccassion = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_multiple_choice, Occassion);
listView_occassion.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView_occassion.setAdapter(adapterOccassion);
mButtonOccassionNext.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),Filters.class);
startActivity(intent);
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
SparseBooleanArray checked = listView_occassion.getCheckedItemPositions();
ArrayList<String> selectedItemsOccassion = new ArrayList<String>();
Utils.occassionArrayList.clear();
for (i = 0; i < checked.size(); i++) {
// Item position in adapter
int position = checked.keyAt(i);
// Add sport if it is checked i.e.) == TRUE!
if (checked.valueAt(i))
// selectedItemsFlavour.add(adapterFlavour.getItem(position));
Utils.occassionArrayList.add(adapterOccassion.getItem(position));
}
}
}
Display second activity as result..
mtv_occassion_status = (TextView) findViewById(R.id.tv_occassion_status);
if(!Utils.occassionArrayList.isEmpty()){
String tempOccassion= String.valueOf(Utils.occassionArrayList);
mtv_occassion_status.setText(tempOccassion);
}
And my array list add in String.xml
<string-array name="occassion_array">
<item>Birthday</item>
<item>Wedding</item>
<item>Anniversary</item>
<item>Celebration</item>
<item>Get Well Soon</item>
<item>House warming</item>
<item>Valentines Day</item>
<item>Diwali</item>
<item>Friendship Day</item>
<item>X-Mas</item>
<item>New Year</item>
<item>Random</item>
</string-array>
Any help would be great for me.
create a class like:
class Occasion {
public String name;
public boolean status;
}
after that create a arraylist:
ArrayList<Occasion> dataList = new ArrayList<>();
and put your items with selection status into this arraylist like this:
String[] occassion = getResources().getStringArray(R.array.occassion_array);
for(int i=0; i < occassion.lenght(); i++){
String name = occasion[i];
Occasion obj = new Occasion();
obj.name = name;
obj.status = getItemStatus(name);
datalist.add(obj);
}
now pass this datalist to your adapter and set the check status on the basis of status parameter of Occasion class
private boolean getItemStatus(String name) {
String items = getSharedPreferences("pref", 0).getString("items", "");
if(items.contains(name){
return true;
}
return false;
}
and
#Override
public void onItemClick(AdapterView adapterView, View view, int i, long l) {
String selectedItemName = dataList.get(i).name;
String items = getSharedPreferences("pref", 0).getString("items", "");
if(!dataList.get(i).status) {
if(items.equals("")) {
items = selectedItemName;
} else {
items = items +","+ selectedItemName;
}
} else {
items = items.replace(selectedItemName, "");
}
SharedPreferences.Editor editor = getSharedPreferences("pref", 0).edit();
editor.putString("items", items);
editor.apply();
dataList.get(i).status = !dataList.get(i).status;
adapter.notifyDataSetChanged();
}
now you have to change your adapter class only. In that class under getView() you have to check the status of each item and select the checkbox accordingly.
Hope this will help you out.
Check this .
for(int i = 0 ; i<adapterOccassion.size ;i++)
{
if(Utils.occassionArrayList.contains(adapterOccassion.getItem(i)))
{
// set checked
}
}

Cannot update dynamic buttons from a Json populated Array

****Working code posted****
I am trying to update buttons where the text will be dynamically programmed from an ArrayList. The data is being retrieved from mySQL. I can get the data in and fill the array with what I need (familyMemberArray). However for some reason when the information is gathered, the program does not go on to implementing the "trending" array or the rest of the layout programming, after the array information has been produced.
I need to formulate the data first so I know how big the array is to create the amount of buttons necessary. If I call in a basic String array it populates the buttons just fine. I remember being stuck on this problem on a uni project and ended up giving up because I just could not get it to work and time was ticking. Please put me out of my misery
public class TrendingMealsFragment extends Fragment {
private TableRow tr;
//SQLite Database
private static final String SELECT_SQL = "SELECT * FROM family_account";
private SQLiteDatabase db;
private Cursor c;
private static final String DATABASE_NAME = "FamVsFam.db";
// Logging
private final String TAG = this.getClass().getName();
private static final String EXTRA_CHALLENGE_ID = "boo.famvsfam.challenge_id";
//Results
private JSONArray resultFamilyMember;
private String dbID;
public static final String JSON_ARRAY = "result";
private List<String> familyMemberArray;
ArrayAdapter<String> adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
openDatabase();
setHasOptionsMenu(true);
c = db.rawQuery(SELECT_SQL, null);
c.moveToFirst();
getRecords();
}
protected void openDatabase() {
db = getActivity().openOrCreateDatabase(DATABASE_NAME, android.content.Context.MODE_PRIVATE, null); // db = SQLiteDatabase.openOrCreateDatabase("FamVsFam", Context.MODE_PRIVATE, null);
}
protected void getRecords() {
dbID = c.getString(0);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getData();
/** Declaring an ArrayAdapter to set items to ListView */
familyMemberArray = new ArrayList<>();
//Menu
setHasOptionsMenu(true);
ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
View view = inflater.inflate(R.layout.activity_resturants, container, false);
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.getSupportActionBar();
/**
ArrayList<String> trending1 = new ArrayList<String>() {
{
add("one");
add("two");
add("three");
add("four");
add("five");
add("six");
add("seven");
add("eight");
add("nine");
add("ten");
add("eleven");
}
};*/
ArrayList<String> trending = new ArrayList<String>() {
{
for(int i = 0; i < familyMemberArray.size() ; i++){
add(familyMemberArray.get(i));
}}
};
// LAYOUT SETTING 1
RelativeLayout root = new RelativeLayout(getActivity());
// root.setId(Integer.parseInt(MEAL_SELECTION_ID));
LayoutParams param1 = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
root.setFitsSystemWindows(true);
}
root.setLayoutParams(param1);
//LAYOUT SETTINGS 2 - TOP BANNER - WITH PAGE HEADING
RelativeLayout rLayout1 = new RelativeLayout(getActivity());
LayoutParams param2 = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
float topBannerDim = getResources().getDimension(R.dimen.top_banner);
param2.height = (int) topBannerDim;
param2.addRule(RelativeLayout.BELOW, root.getId());
int ele = (int) getResources().getDimension(R.dimen.elevation);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
rLayout1.setElevation(ele);
}
rLayout1.setBackgroundColor(Color.parseColor("#EEEBAA"));
rLayout1.setLayoutParams(param2);
//TEXT VIEW
TextView text1 = new TextView(getActivity());
text1.setText(R.string.diet_req);
LayoutParams param3 = new LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
param3.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
text1.setTextColor(Color.parseColor("#8A1F1D"));
text1.setTypeface(Typeface.DEFAULT_BOLD);
text1.setLayoutParams(param3);
//LAYOUT SETTINGS 4
RelativeLayout rLayout4 = new RelativeLayout(getActivity());
LayoutParams param5 = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
topBannerDim = getResources().getDimension(R.dimen.top_banner);
param5.height = (int) topBannerDim;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
param5.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.ALIGN_START);
}
param5.addRule(RelativeLayout.BELOW, rLayout1.getId());
rLayout4.setId(R.id.id_relative_4);
rLayout4.setBackgroundColor(Color.parseColor("#EEEBAA"));
rLayout4.setLayoutParams(param5);
//LAYOUT SETTINGS 5
TableLayout rLayout5 = new TableLayout(getActivity());
rLayout5.setOrientation(TableLayout.VERTICAL);
LayoutParams param7 = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
param7.addRule(RelativeLayout.BELOW, rLayout4.getId());
rLayout5.setBackgroundColor(Color.parseColor("#EEEBAA"));
rLayout5.setLayoutParams(param7);
// List<ToggleButton> togButtStore = new ArrayList<ToggleButton>();
int i = 0;
while (i < trending.size()) {
if (i % 3 == 0) {
tr = new TableRow(getActivity());
rLayout5.addView(tr);
}
ToggleButton toggleBtn = new ToggleButton(getActivity());
toggleBtn.setText(trending.get(i));
toggleBtn.setId(i);
toggleBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
Context context = getActivity().getApplicationContext();
CharSequence text = "Hello toast!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
} else {
// The toggle is disabled
}
}
});
tr.addView(toggleBtn);
i++;
}
//LAYOUT SETTINGS 6
FrameLayout youBeenFramed = new FrameLayout(getActivity());
LayoutParams param8 = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
param8.addRule(RelativeLayout.BELOW, rLayout5.getId());
youBeenFramed.setBackgroundColor(Color.parseColor("#EEEBAA"));
root.addView(youBeenFramed);
root.addView(rLayout1);
rLayout1.addView(text1);
root.addView(rLayout4);
root.addView(rLayout5);
getActivity().setContentView(root);
return view;
}
public void getData() {
//// TODO: 03/08/2016 Progress Dialogs : on getting data
// final ProgressDialog loading = ProgressDialog.show(getActivity(), "Loading Data", "Please wait...", false, false);
StringRequest strReq = new StringRequest(Request.Method.POST,
PHPConfigURLS.URL_ALL_FAMILY_MEMBERS, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Login Response: " + response.toString());
JSONObject j = null;
try {
// loading.dismiss();
//Parsing the fetched Json String to JSON Object
j = new JSONObject(response);
//Storing the Array of JSON String to our JSON Array
resultFamilyMember = j.getJSONArray(JSON_ARRAY);
//Calling method getStudents to get the students from the JSON Array
getDBFamilyName(resultFamilyMember);
} catch (JSONException e) {
// JSON error
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Map<String, String> getParams() {
String id = dbID;
// Posting params to register url
Map<String, String> params = new HashMap<String, String>();
params.put("id", id);
// params.put("email", email);
// params.put("password", password);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
//Adding request to the queue
requestQueue.add(strReq);
}
private void getDBFamilyName(JSONArray j) {
//Traversing through all the items in the json array
for (int i = 0; i < j.length(); i++) {
FamilyAccount familyMember = new FamilyAccount();
try {
//Getting json object
JSONObject json = j.getJSONObject(i);
familyMember = new FamilyAccount();
familyMember.setName(json.getString("name"));
familyMember.setID(json.getInt("id"));
} catch (JSONException e) {
e.printStackTrace();
}
//Adding the title of the challenge to array list
familyMemberArray.add(familyMember.getName());
}
}
}
Thanks in advance
for some reason when the information is gathered, the program does not go on to implementing the "trending" array or the rest of the layout programming, after the array information has been produced.
That's because the layout doesn't "dynamically" update when you call this when the request finishes.
familyMemberArray.add(familyMember.getName());
You'll have to clear the view, and redo all the view adding again, or "extract" all the view generation code into it's own method that you can call with the parameter of your ArrayList.
Basically, everything between // LAYOUT SETTING 1 and return view (non-inclusive) needs to be moved into a public void generateView(ArrayList<String> familyMemberArray) method that can optionally return the root View that was generated, if necessary.
Then, at the end of getFamilyName(), outside the loop, call that method with your ArrayList.
I need to formulate the data first so I know how big the array is to create the amount of buttons necessary.
I'm not sure I see where you are doing that. Unless you mean here
while (i < trending.size()) {
Which, instead, trending is an entirely different list reference than familyMemberArray, so it won't update either. Though, it contains the exact same data?
ArrayList<String> trending = new ArrayList<String>() {
{
for(int i = 0; i < familyMemberArray.size() ; i++){
add(familyMemberArray.get(i));
}}
};
That block of code looks a bit odd, considering the ArrayList constructor already provides that functionality
ArrayList<String> trending = new ArrayList<String>(familyMemberArray);
*****WORKING CODE****** Credit to cricket_007
FIELDS
public class TrendingMealsFragment extends Fragment {
// Logging
private final String TAG = this.getClass().getName();
//Results
private JSONArray resultFamilyMember;
public static final String JSON_ARRAY = "result";
private ArrayList<String> familyMemberArray;
//Layout
private TableRow tr;
OnCreateView()
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_resturants, container, false);
generateView(familyMemberArray);
getData();
return view;
}
GetData()
public void getData() {
StringRequest strReq = new StringRequest(Request.Method.POST,
PHPConfigURLS.URL_ALL_FAMILY_MEMBERS, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Login Response: " + response.toString());
JSONObject j = null;
try {
//Parsing the fetched Json String to JSON Object
j = new JSONObject(response);
//Storing the Array of JSON String to our JSON Array
resultFamilyMember = j.getJSONArray(JSON_ARRAY);
//Calling method getStudents to get the students from the JSON Array
getDBFamilyName(resultFamilyMember);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Map<String, String> getParams() {
String id = dbID;
Map<String, String> params = new HashMap<String, String>();
params.put("id", id);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
//Adding request to the queue
requestQueue.add(strReq);
}
getDBFamilyName()
private void getDBFamilyName(JSONArray j) {
//Traversing through all the items in the json array
for (int i = 0; i < j.length(); i++) {
FamilyAccount familyMember = new FamilyAccount();
try {
//Getting json object
JSONObject json = j.getJSONObject(i);
familyMember = new FamilyAccount();
familyMember.setName(json.getString("name"));
familyMember.setID(json.getInt("id"));
} catch (JSONException e) {
e.printStackTrace();
}
//Adding the title of the challenge to array list
familyMemberArray.add(familyMember.getName());
generateView(familyMemberArray);
}
}
generateView()
public View generateView(ArrayList<String> familyMemberArray) {
...
rLayout5.setLayoutParams(param7);
//Create Buttons
int i = 0;
while (i < familyMemberArray.size()) {
if (i % 3 == 0) {
tr = new TableRow(getActivity());
rLayout5.addView(tr);
}
ToggleButton toggleBtn = new ToggleButton(getActivity());
toggleBtn.setText(familyMemberArray.get(i));
toggleBtn.setId(i);
toggleBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
Context context = getActivity().getApplicationContext();
CharSequence text = "Hello toast!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
} else {
// The toggle is disabled
}
}
});
tr.addView(toggleBtn);
i++;
}
...
root.addView(rLayout5);
getActivity().setContentView(root);
return root;
}
}

ListItems ArrayList ListView

Guys I'm trying to make the below code store multiple items in exampleArray but it's only grabbing the first SectionOutageListItem. Do I need to create another listItem Array to loop through it again?
SectionOutageListItem[] exampleArray = new SectionOutageListItem[outnums.size()];
for(int i = 0; i < outnums.size(); i++) {
exampleArray[i] =
new SectionOutageListItem("Impact", impacted.get(i), "Outage No. " + outnums.get(i)),
new SectionOutageListItem("status", status.get(i), "Outage No. " + outnums.get(i));
}
CustomOutageDetailListAdapter adapter = new CustomOutageDetailListAdapter(this, exampleArray);
sectionAdapter = new SectionOutageListAdapter(getLayoutInflater(),
adapter);
UPDATE:
I have a custom adapter which adds sections to a listview, the SectionOutageListItem determines how many rows are in that section. The outnums.get(i) creates multiple sections which should add the impact and status as rows for each section. It is only adding the first new SectionOutageListItem as a row and not the second one.
Custom List Adapter code
public class CustomOutageDetailListAdapter extends ArrayAdapter<SectionOutageListItem> {
private Activity context;
private SectionOutageListItem[] items;
//private final ArrayList<String> itemname;
public CustomOutageDetailListAdapter(Activity context, SectionOutageListItem[] items) {
super(context, R.layout.mylistoutagedetails, items);
this.items= items;
this.context = context;
}
#Override
public View getView(int position,View view,ViewGroup parent) {
LayoutInflater inflater=context.getLayoutInflater();
View rowView=inflater.inflate(R.layout.mylistoutagedetails, null,true);
final SectionOutageListItem currentItem = items[position];
if (currentItem != null) {
TextView txtTitle = (TextView) rowView.findViewById(R.id.item);
TextView txtName = (TextView) rowView.findViewById(R.id.name);
if (txtTitle != null) {
txtTitle.setText(currentItem.item.toString());
}
if (txtName != null) {
txtName.setText(currentItem.name.toString());
}
}
return rowView;
};
As #Trobbins points out ,
You may need to change the code as follows,
SectionOutageListItem[][] exampleArray = new SectionOutageListItem[outnums.size()][2];
for(int i = 0; i < outnums.size(); i++) {
exampleArray[i][0] =
new SectionOutageListItem("Impact", impacted.get(i), "Outage No. " + outnums.get(i));
exampleArray[i][1] = new SectionOutageListItem("status", status.get(i), "Outage No. " + outnums.get(i));
}
CustomOutageDetailListAdapter adapter = new CustomOutageDetailListAdapter(this, exampleArray);
sectionAdapter = new SectionOutageListAdapter(getLayoutInflater(),
adapter);
You can also go with a Map specifically LinkedHashMap if you want to maintain the insertion order or else HashMap

Searching and deleting rows in Custom ListView

I'm trying to create a ListView for a Friends list. It has a search functiton in which tthe user can search for a particular freind and then delete them as a friend, message them and so forth.
However, I'm having trouble removing them. I don't think I understand the positioning, or finding out the correct position on where the users freind is in the list.
I want to make sure that in all cases, the user is removed from the correct position. For instance, if the user uses the search function and only one user is returned. Then I don't want the user to be removed at position 0 (one user), I want it to be removed at the correct position so that when the user goes back to the full list. Position 0 in the list isn't accidentaly removed.
Could someone review the code? and show a slight indication as to where I am going wrong with this?
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
res = getResources();
searchField = (EditText) findViewById(R.id.EditText01);
lv = (ListView) findViewById(android.R.id.list);
//button = (Button)findViewById(R.id.btnFriendList);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
//button.setFocusable(false);
list = new ArrayList<Friend>();
nameBlock = res.getStringArray(R.array.names);
descBlock = res.getStringArray(R.array.descriptions);
names = new ArrayList<String>();
for(int i = 0; i < nameBlock.length; i++) {
names.add((String)nameBlock[i]);
}
descr = new ArrayList<String>();
for(int i = 0; i < descBlock.length; i++) {
descr.add((String)descBlock[i]);
}
images = new ArrayList<Integer>();
for(int i = 0; i < imageBlock.length; i++) {
images.add((Integer)imageBlock[i]);
}
//imageBlock = res.getIntArray(R.array.images);
int size = nameBlock.length;
for(int i = 0 ; i < size; i++) {
Log.d("FREINDADD", "Freind Added" + i);
list.add(new Friend(i, names.get(i), descr.get(i), images.get(i)));
//friendList2.add(new Friend(i, names.get(i), descr.get(i), images.get(i)));
}
Log.i("Application", "Application started succesfully...");
adapter = new CustomAdapter(this);
setListAdapter(adapter);
Log.i("VIRTU", "Count" + adapter.getCount());
//adapter.getCount();
searchField.addTextChangedListener(new TextWatcher()
{
#Override public void afterTextChanged(Editable s) {}
#Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override public void onTextChanged(CharSequence s, int start, int before, int count)
{
list.clear();
textlength = searchField.getText().length();
for (int i = 0; i < names.size(); i++)
{
if (textlength <= names.get(i).length())
{
if(names.get(i).toLowerCase().contains(searchField.getText().toString().toLowerCase().trim())) {
Log.i("VirtuFriendList", "List recyling in process... ");
list.add(new Friend(i, names.get(i), descr.get(i), images.get(i)));
}
}
}
AppendList(list);
}
});
}
public void AppendList(ArrayList<Friend> list) {
setListAdapter(new CustomAdapter(this));
}
class CustomAdapter extends BaseAdapter {
private Context context;
public CustomAdapter(Context context) {
this.context = context;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return list.size();
}
class ViewHolder {
TextView userName;
TextView userDesc;
ImageView userImage;
Button userButton;
ViewHolder(View view) {
userImage = (ImageView)view.findViewById(R.id.imageview);
userName = (TextView)view.findViewById(R.id.title);
userDesc = (TextView)view.findViewById(R.id.mutualTitle);
userButton = (Button)view.findViewById(R.id.btn);
}
}
ViewHolder holder;
View row;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
row = convertView;
if(row == null)
{
// If it is visible to the user, deploy the row(s) - allocated in local memory
LayoutInflater inflater = (LayoutInflater)context .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.search_list_item, parent, false);
holder = new ViewHolder(row);
row.setTag(holder);
Log.d("VIRTU", "Row deployed...");
}
else
{
// Recycle the row if it is not visible to to the user - store in local memory
holder = (ViewHolder)row.getTag();
Log.d("VIRTU", "Row recycled...");
}
Friend temp = list.get(position);
// Set the resources for each component in the list
holder.userImage.setImageResource(temp.getImage());
holder.userName.setText(temp.getName());
holder.userDesc.setText(temp.getDesc());
((Button)row.findViewById(R.id.btn)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PopupMenu pop = new PopupMenu(getApplicationContext(), v);
MenuInflater inflater = pop.getMenuInflater();
inflater.inflate(R.menu.firned_popup_action,pop.getMenu());
pop.show();
pop.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
int choice = item.getItemId();
switch(choice) {
case R.id.message:
break;
case R.id.unfollow:
break;
case R.id.unfriend:
int position = (Integer)row.getTag();
list.remove(position);
names.remove(position);
images.remove(position);
descr.remove(position);
adapter = new CustomAdapter(context);
lv.setAdapter(adapter);
adapter.notifyDataSetChanged();
break;
case R.id.cancel:
}
return false;
}
});
}
});
return row;
}
}
}
I think as your structure stands, you will continue to have this problem. My suggestion would be to assign a FriendID (or something similar) to each friend, and when you are building your list, instead of just passing userImage, userName, userDesc and userButton, pass along friendID as well.
For example, I have five friends, and here is their information:
userImage userName userDesc userButton friendID
x Jordyn x x 0
x Sam x x 1
x Connor x x 2
x Paul x x 3
x Raphael x x 4
But my search for (pretending you can search by one letter) those with 'o' in their name returns,
userImage userName userDesc userButton friendID
x Jordyn x x 0
x Connor x x 2
That way, when you delete the 1th row, it actually removes friendID = 2 from your friend list instead of the 1th row from your original friend list, which would've been Sam, which was not your intention.
Hope that helps!
EDIT:
1: add a hidden TextView to your rows called FriendID in your layout file (let me know if you need help with that).
Now, ViewHolder will look like this:
class ViewHolder {
TextView userName;
TextView userDesc;
ImageView userImage;
Button userButton;
TextView friendID;
ViewHolder(View view) {
userImage = (ImageView)view.findViewById(R.id.imageview);
userName = (TextView)view.findViewById(R.id.title);
userDesc = (TextView)view.findViewById(R.id.mutualTitle);
userButton = (Button)view.findViewById(R.id.btn);
friendID = (TextView)view.findViewById(R.id.friendID);
}
}
2: add an arraylist for the friendIDs:
...
descr = new ArrayList<String>();
for(int i = 0; i < descBlock.length; i++) {
descr.add((String)descBlock[i]);
}
images = new ArrayList<Integer>();
for(int i = 0; i < imageBlock.length; i++) {
images.add((Integer)imageBlock[i]);
}
friendIDs = new ArrayList<Integer>();
for(int i = 0; i < friendIDsBlock.length; i++) {
images.add((Integer)friendIdsBlock[i]);
}
...
3: searchField.addTextChangedListener will now look like:
int size = nameBlock.length;
for(int i = 0 ; i < size; i++) {
Log.d("FREINDADD", "Freind Added" + i);
list.add(new Friend(i, names.get(i), descr.get(i), images.get(i)));
//friendList2.add(new Friend(i, names.get(i), descr.get(i), images.get(i), friendIds.get(i)));
}
Log.i("Application", "Application started succesfully...");
4: Now, when you unfriend someone, make sure to get the FriendID at the selected row as opposed to the row index. Then, remove the friend from the search list with the given FriendID as well as the friend from the general friend list with the given FriendID.
You'll have to forgive me, I don't have an IDE in front of me at the moment but I think that about covers it!

Sorting a ListView with ArrayAdapter<String>

I have a custom ListView, each list item has four TextViews showing bank name, amount, date and time. This data is stored in a database. The idea is that on the Activity there is a quick action dialog which opens on clicking the sort button. The Dialog has three options as "Sort by bank name" ascending order, "Sort by Date" newest first and "Sort by amount" larger amount in the top of the list. I don't have any idea of how to proceed with the sorting task to be written in onItemClick(int pos). Can anyone please help me on this?
public class TransactionMenu extends Activity implements OnItemClickListener, OnActionItemClickListener {
String[] TransId ;
String[] mBankName;
String[] mAmount;
String[] mDate;
String[] mTime;
Button SortButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.transaction_screen);
SortButton = (Button)findViewById(R.id.sortKey);
//Bank Name action item
ActionItem bName = new ActionItem();
bName.setTitle("Bank Name");
bName.setIcon(getResources().getDrawable(R.drawable.bank_256));
//Amount action item
ActionItem amt = new ActionItem();
amt.setTitle("Amount");
amt.setIcon(getResources().getDrawable(R.drawable.cash));
//date action item
ActionItem date = new ActionItem();
date.setTitle("Date");
date.setIcon(getResources().getDrawable(R.drawable.calender));
//create quickaction
final QuickAction quickAction = new QuickAction(this);
quickAction.addActionItem(bName);
quickAction.addActionItem(amt);
quickAction.addActionItem(date);
quickAction.setOnActionItemClickListener(this);
SortButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
quickAction.show(v);
//quickAction.setAnimStyle(QuickAction.ANIM_REFLECT);
}
});
DBAdapter lDBAdapter = new DBAdapter(this);
lDBAdapter.open();
/* getTransDetails() returns all the detials stored in the transaction table*/
Cursor mCursor =lDBAdapter.getAllTransDetails();
System.out.println("cur..........."+mCursor);
lDBAdapter.close();
if (mCursor != null) {
int size = mCursor.getCount();
if (mCursor.moveToFirst()) {
TransId = new String[size];
mAmount = new String[size];
mBankName = new String[size];
mDate = new String[size];
mTime = new String[size];
for (int i = 0; i < size; i++, mCursor.moveToNext()) {
TransId[i] = mCursor.getString(0);
mAmount[i] = mCursor.getString(1);
mBankName[i] = mCursor.getString(3);
mDate[i] = mCursor.getString(2);
mTime[i] = mCursor.getString(4);
}
}
}
for (int i = 0; i < mCursor.getCount(); i++) {
System.out.println("TransId is+++++++++++++++ "+TransId[i]);
System.out.println("amount is+++++++++++++++ "+mAmount[i]);
System.out.println("bankName is+++++++++++++++ "+mBankName[i]);
System.out.println("date is+++++++++++++++ "+mDate[i]);
System.out.println("time is+++++++++++++++ "+mTime[i]);
}
ListView myListView = (ListView) findViewById(R.id.transactionListView);
MyBaseAdapter myAdapterObj = new MyBaseAdapter(TransactionMenu.this, R.layout.list_item, TransId);
myListView.setAdapter(myAdapterObj);
myListView.setOnItemClickListener((OnItemClickListener) this);
}
private class MyBaseAdapter extends ArrayAdapter<String> {
public MyBaseAdapter(Context context, int textViewResourceId, String[] transId) {
super(context, textViewResourceId, transId);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.list_item, parent, false);
TextView label = (TextView)row.findViewById(R.id.textview1);
label.setText("Amount: "+mAmount[position]);
TextView label1 = (TextView) row.findViewById(R.id.textview2);
label1.setText("Bank Name: "+mBankName[position]);
TextView label2 = (TextView) row.findViewById(R.id.textview3);
label2.setText("Date: "+mDate[position]);
TextView label3 = (TextView) row.findViewById(R.id.textview4);
label3.setText("Time: "+mTime[position]);
return row;
}
}
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
System.out.println("arg2 is++++++++++++++"+arg2);
int lRowId = Integer.parseInt(TransId[arg2]);
}
public void onItemClick(int pos) {
MyBaseAdapter myAdapterObj = new MyBaseAdapter(TransactionMenu.this, R.layout.list_item, TransId);
if (pos == 0) {
Toast.makeText(TransactionMenu.this, "Bank name item selected", Toast.LENGTH_SHORT).show();
}
else if (pos ==1) {
Toast.makeText(TransactionMenu.this, "amount item selected", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(TransactionMenu.this, "Date item selected", Toast.LENGTH_SHORT).show();
}
}
}
I will give you the way i would do this, not the best probably but it will work fine.
Fisrt of all as user7777777777 said it's better to keep related infos into the same object so i'd define BankInfo class as shown below:
private class BankInfo{
String TransId ;
String mBankName;
String mAmount;
String mDate;
String mTime;
public BankInfo(String TransId,String mBankName,String mAmount,String mDate,String mTime)
{
//fields init
}
}
once you have this you will define an Array of this object BankInfo[] trans. In the adapter you can use this array to bind values into views.
then to manage to implement the sorting function the thing i would do is to put a static variable into the BankInfo class and override the CompareTo() method to use that field:
static int AMMOUNT = 0;
static int DATE = 1;
static int NAME = 2;
static public int sort_by;
public int compareTo(BankInfo info){
switch (sorty_by){
case(AMMOUNT):
return //compare by ammount
case(DATE):
return //compare by date
case(NAME):
return //compare by name
}
}
with this inside of BankInfo you will have only to add your array to a TreeSet<BankInfo> and all your item will be sortet using the compareTo() method.
Inside the adapter put this method to sort elements in the adapter
public void sort_datas(int sort_by);
{
//set the type of sort you want
BankInfo.sortBy = sort_by;
//build a Sorted treeSet by the BankInfo array
TreeSet<BankInfo> sorted_info = new TreeSet<BankInfo>();
list.addAll(Arrays.asList(trans));
//replace the BankInfo array with the new sorted one
trans = (BankInfo[])sorted_info.toArray();
//notify to the adapter that the data set changed
notifyDataSetChanged();
}
You can use the following code. You need to maintain the bank info in a BankInfo object. Create an ArrayList of BankInfo objects and then you can use this code. Its not a good practice to keep related info into separate arrays.
Collections.sort(mBankInfoArrayList, new Comparator<BankInfo>() {
int compare(BankInfo obj1, BankInfo obj2) {
return obj1.getBankName().compareToIgnoreCase(obj2.getBankName());
}
});

Categories