I created a custom ArrayAdapter and inside the ArrayAdapter there's a LinearLayout that adds views via iteration. Now after showing the data that needs to be shown on a ListView all will be well until I scroll down or up the list, when a row undergoes recycling and binding the new view to display on the recycled row I get duplicates, however this duplicates have show no data(text) on the views. Here is the view ListView before scrolling
https://postimg.org/image/z36eqhacd/
and here is the ListView after scrolling
https://postimg.org/image/dzv28kj9t/
I've tried multiple methods but can't seem to get it to work.
public class SurveyAdapter extends ArrayAdapter<SurveyModel> {
public SurveyAdapter(Context context, ArrayList<SurveyModel> objects) {
super(context, R.layout.survey_card, objects);
}
#NonNull
#Override
public View getView(int position, View convertView, #Nullable ViewGroup parent) {
//Get the data item for this position
SurveyModel surveyModel = getItem(position);
//Construct the ViewHolder
ViewHolder viewHolder = new ViewHolder();
//Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
//If there's no view to re-use, inflate a new view for a row
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.survey_card, parent, false);
viewHolder.mContainer = (LinearLayout) convertView.findViewById(R.id.choice_container);
viewHolder.question = (TextView) convertView.findViewById(R.id.question);
//Cache the viewHolder object inside the new view
convertView.setTag(viewHolder);
} else {
//View is being recycled, retrieve the viewHolder object from tag
viewHolder = (ViewHolder) convertView.getTag();
}
assert surveyModel != null;
//Populate the data from the data object
String choices = surveyModel.getChoice();
//Scan each string separately
//Strings are separated with a comma ','
Scanner scanner = new Scanner(choices).useDelimiter(",\\s*");
//Create an array list to store each string separately
ArrayList<String> choiceList = new ArrayList<>();
//Get all strings from scanner separately
while (scanner.hasNext()) {
String choice = scanner.next(); //Get each string from scanner
choiceList.add(choice); //Store the string in an ArrayList(choiceList)
}
//Convert choiceList(ArrayList) to a StringArray(choiceArray)
String[] choiceArray = choiceList.toArray(new String[choiceList.size()]);
int choiceNum; //Will store number of choices to be displayed
if (choices.contains("Other,true") || choices.contains("Other,false")) {
//Set number or choices to the length(number of items) of the choiceList(ArrayList)
//Minus 1 to avoid showing "true" as an option
choiceNum = choiceArray.length - 1;
} else {
//Set number or choices to the length(number of items) of the array
choiceNum = choiceArray.length;
}
//Get number of choices from choiceNum
final int numOfChoices = choiceNum;
//Populate each choice string from choiceArray
for (int i = 0; i < numOfChoices; i++) {
//Create a new CheckBox for each choice
AppCompatCheckBox checkBox = new AppCompatCheckBox(getContext());
checkBox.setLayoutParams(new LinearLayoutCompat.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
//Add the CheckBox to its survey_view_list view(mContainer)
viewHolder.mContainer.addView(checkBox);
if (viewHolder.mContainer.getChildAt(i) instanceof AppCompatCheckBox) {
//Set each data item in the choiceArray on its own CheckBox according to position
((AppCompatCheckBox) viewHolder.mContainer.getChildAt(i)).setText(choiceArray[i]);
final ViewHolder finalViewHolder = viewHolder; //Get viewHolder for inner class access
final int checkBoxPosition = i; //Set position of the checked CheckBox
((AppCompatCheckBox) viewHolder.mContainer.getChildAt(i)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
if (checked) {
for (int i = 0; i < numOfChoices; i++) {
//Disable all CheckBoxes when a CheckBox is checked
finalViewHolder.mContainer.getChildAt(i).setEnabled(false);
//Re-enable the checked CheckBox only
finalViewHolder.mContainer.getChildAt(checkBoxPosition).setEnabled(true);
}
} else {
for (int i = 0; i < numOfChoices; i++) {
//Enable all CheckBoxes when the checked CheckBox is unchecked
finalViewHolder.mContainer.getChildAt(i).setEnabled(true);
}
}
}
});
}
}
//Populate the data from the data object via the viewHolder object into the view
viewHolder.question.setText(surveyModel.getQuestion());
//Return the completed view to render on screen
return convertView;
}
//View lookup cache
private static class ViewHolder {
LinearLayout mContainer;
TextView question;
}`
Here is the Object Model
public class SurveyModel {
private String question, choice;
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getChoice() {
return choice;
}
public void setChoice(String choice) {
this.choice = choice;
}
}
Here is the method from the Activity I attach the ArrayAdapter to a ListView
//Method to populate and display data populated from the database
private void populateAndDisplayData() {
//Construct ArrayList
ArrayList<SurveyModel> surveyModelArrayList = new ArrayList<>();
//Construct adapter
SurveyAdapter adapter = new SurveyAdapter(CreateFromScratch.this, surveyModelArrayList);
//Attach the adapter to the ListView
binding.list.setAdapter(adapter);
//Create a ListView
ListView listView = new ListView(CreateFromScratch.this);
//Get all the data from the database
Cursor allDataCursor = tempSurveyDatabase.fetchAllData();
//StringArray to hold the strings from the database
String[] from = new String[]{CustomSurveyDatabase.QUESTION, CustomSurveyDatabase.CHOICES};
//Views to display the string data from StringArray(from)
int[] to = new int[]{R.id.question, R.id.choices};
//Construct a SimpleCursorAdapter
SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(CreateFromScratch.this, R.layout.survey_card, allDataCursor, from, to);
// /Attach the adapter to the ListView
listView.setAdapter(simpleCursorAdapter);
//Construct StringBuilder
StringBuilder jsonBuilder = new StringBuilder();
//Strings to hold the item's data from the database
String question = null;
String choices = null;
//Proceed with collecting each item's data if the SimpleCursorAdapter is not empty
if (simpleCursorAdapter.getCount() > 0) {
//Get every item's id from the database
for (int i = 0; i < simpleCursorAdapter.getCount(); i++) {
//Get each item's database id
long itemId = listView.getAdapter().getItemId(i);
//Get each item from the database
try {
//Construct cursor to fetch an item's data from the database
Cursor cursor = tempSurveyDatabase.fetchItem(itemId);
question = tempSurveyDatabase.questionHolder;
choices = tempSurveyDatabase.choiceHolder;
} catch (SQLException e) {
Log.v(TAG, e.getMessage());
}
if (i == 0) {
jsonBuilder.append("{\"survey\": [").append("{\"question\":\"").append(question).append("\",");
jsonBuilder.append("\"choices\":\"").append(choices).append("\"},");
} else {
jsonBuilder.append("{\"question\":\"").append(question).append("\",");
jsonBuilder.append("\"choices\":\"").append(choices).append("\"},");
}
}
//Remove the last comma from the StringBuilder
jsonBuilder.deleteCharAt(jsonBuilder.length() - 1);
//Close JSON file scopes
jsonBuilder.append("]}");
//Save temporary survey file on the SDCARD
try {
//Delete existing temporary survey
if (TEMP_SURVEY.exists()) {
//noinspection ResultOfMethodCallIgnored
TEMP_SURVEY.delete();
}
FileWriter fileWriter = new FileWriter(TEMP_SURVEY);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(String.valueOf(jsonBuilder));
bufferedWriter.close();
} catch (IOException e) {
Log.v(TAG, "Temp Survey JSON file failed to write.\nReason: " + e.getMessage());
}
//Check if the temporary survey file exists
if (TEMP_SURVEY.exists()) {
//Read the temporary survey file if it exists
new ReadFile(ReadFile.data, ReadFile.output, TEMP_SURVEY);
//Parse JSON string from StringBuilder
try {
JSONObject jsonObjectMain = new JSONObject(ReadFile.output);
JSONArray jsonArray = jsonObjectMain.getJSONArray(SurveyJSONKeys.ARRAY_KEY);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
SurveyModel surveyModel = new SurveyModel();
surveyModel.setQuestion(jsonObject.getString(SurveyJSONKeys.QUESTION_KEY));
surveyModel.setChoice(jsonObject.getString(SurveyJSONKeys.CHOICES_KEY));
surveyModelArrayList.add(surveyModel);
}
} catch (JSONException e) {
Log.v(TAG, "Unable to parse JSON file.\nReason: " + e.getMessage());
}
//Notify the adapter for changes in order to refresh views
adapter.notifyDataSetChanged();
}
}
}`
Since your item view is recycled every time, the container of your answers are just appended with more answers. You have 2 options:
Remove all child views in your container before populating with answers
Do not force a recycle by using getViewTypeCount() and getItemViewType(int).
Related
I am new in android and I am trying to get the duplicate values in an array list. I have searched over the internet but I got nothing.
My project has two array lists one is for numbers and the second one is for displaying them. And if the first array list contains a duplicate values, the second one will display all the values and the duplicate ones will be displayed with a stars to mark them as a duplicate values.
So I have tried the following code but I have got nothing. In this situation, array list contains [9,9,5,7].
The problem is I do not get what I need, here is my code.
Note that: arrayList object that contains the numbers, array object will display them.. So any help on this?
arrayList.add(Integer.valueOf(students.getSeatnum()));
array.add(students.getStuden_name() + ", Student " + students.getStudent_id() + ", Seat Num: " + students.getSeatnum());
Set<Integer> seenValues = new HashSet();
for(Integer value: arrayList) {
if(seenValues.contains(value)) {
array.add(students.getStuden_name() + ", Student " + students. getStudent_id() + ", Seat Num: " + students.getSeatnum()+ "****");
adapter = new ArrayAdapter<String>(StudentInfo.this, android.R.layout.simple_list_item_1, array);
listView.setAdapter(adapter);
} else {
adapter = new ArrayAdapter<String>(StudentInfo.this, android.R.layout.simple_list_item_1, array);
listView.setAdapter(adapter);
}
}
Create an Adapter which accepts arrayList you have created.
Assuming you are using ListView from your variable name convention.
public class MySimpleArrayAdapter extends ArrayAdapter<String> {
private final Context context;
private final List<String> values;
public MySimpleArrayAdapter(Context context, List<String> values) {
super(context, -1, values);
this.context = context;
this.values = values;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context. getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.label);
textView.setText(values.get(position));
return rowView;
}
}
Your method will look like this
ArrayList<String> array = new ArrayList<>();
Map<Integer,Integer> seenValues = new HashMap<>();
int i=0;
for(int value : arrayList){
if(seenValues.containsKey(value)){
if(seenValues.get(value) !=-1){
array.set(seenValues.get(value), String.valueOf(value) + "*");
seenValues.put(value,-1);
}
array.add(String.valueOf(value)+"*");
}else{
array.add(String.valueOf(value));
seenValues.put(value,i);
}
i++;
}
MySimpleArrayAdapter adapter = new adapter(context,array);
setListAdapter(adapter);
You can do it this way:
public class Test {
List<Integer> digits ;
List<String> digitsWatch;
public Test() {
digits = Arrays.asList(9,9,9,5,7,3,3);
digitsWatch = new ArrayList<>(digits.size());
// copying your array
for (int i = 0; i < digits.size(); i++) {
digitsWatch.add(digits.get(i).toString());
}
//filtred values
boolean hasDublicaqtes = false;
for (int i = 0; i < digits.size() -1 ; i++) {
for (int j = i +1; j < digits.size() ; j++) {
if(digitsWatch.get(j).equals(digits.get(i).toString()) ) {
hasDublicaqtes = true;
String tmp = digitsWatch.get(i) + "*";
digitsWatch.set(j,tmp);
}
}
if(hasDublicaqtes) {
String tmp = digitsWatch.get(i) + "*";
digitsWatch.set(i,tmp);
}
hasDublicaqtes = false;
}
}
}
Maybe it's not an optimal way but it works!
I have 2 xml files
Header and Section
then i use some condition to segregate those two and the output of that is this
|8/2/2018|
----------
Data 1
Data 2
|8/2/2018|
----------
Data 1
Data 2
Data 3
It is a listview that groups data with same date and the 1 date header for them.
My question is how can I count each data then update the header? like this
|8/2/2018 (2)|
----------
Data 1
Data 2
|8/2/2018 (3)|
----------
Data 1
Data 2
Data 3
Im using Listview and ListAdapter extends ArrayAdapter
where do i will update?
here
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ItemModel cell = (ItemModel) getItem(position);
if (cell.isSectionHeader()) {
//Display Date in Header XML
} else {
//Display in Section XML
}
}
or here
private ArrayList sortAndAddSections(ArrayList<ItemModel> itemList) {
ArrayList<ItemModel> tempList = new ArrayList<>();
Collections.sort(itemList);
String header = "";
for (int i = 0; i < itemList.size(); i++) {
if (!(header.equals(itemList.get(i).getDate()))) {
String data = itemList.get(i).getRemarks();
String date = itemList.get(i).getDate()
ItemModel sectionCell = new ItemModel(date,data);
sectionCell.setToSectionHeader();
tempList.add(sectionCell);
header = itemList.get(i).getDate();
}
tempList.add(itemList.get(i));
}
return tempList;
}
Updated
Here is how I transfer the data from database to array
private ArrayList<ItemModel> getItems() {
Cursor data = myDb.get_plan(email);
ArrayList<ItemModel> items = new ArrayList<>();
while (data.moveToNext()) {
String date = data.getString(3);
String data1 = data.getString(4);
items.add(new ItemModel(date,data1));
}
return items;
}
then this where the condition goes
private ArrayList sortAndAddSections(ArrayList<ItemModel> itemList) {
ArrayList<ItemModel> tempList = new ArrayList<>();
String header = "";
for (int i = 0; i < itemList.size(); i++) {
if (!(header.equals(itemList.get(i).getDate()))) {
String date = itemList.get(i).getDate();
String getData1 = itemList.get(i).getData1();
ItemModel sectionCell = new ItemModel(date,data1);
sectionCell.setToSectionHeader();
tempList.add(sectionCell);
header = itemList.get(i).getDate();
}
tempList.add(itemList.get(i));
}
return tempList;
}
this is where i set it in textview
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ItemModel cell = (ItemModel) getItem(position);
if (cell.isSectionHeader()) {
v = inflater.inflate(R.layout.section_header, null);
v.setClickable(false);
TextView header = (TextView) v.findViewById(R.id.list_date);
header.setText(cell.getDate());
} else {
v = inflater.inflate(R.layout.listview_plan, null);
TextView tv_data1 = v.findViewById(R.id.list_data1);
tv_cusname.setText(cell.getData1());
}
return v;
}
Try this:
private ArrayList sortAndAddSections(ArrayList<ItemModel> itemList) {
ArrayList<ItemModel> tempList = new ArrayList<>();
ArrayList<Integer> tmpHeaderPositions = new ArrayList<>(); // Added
String header = "";
ItemModel sectionCell; // Changed
int addedRow = 0; // Edited
for (int i = 0; i < itemList.size(); i++) {
if (!(header.equals(itemList.get(i).getDate()))) {
String date = itemList.get(i).getDate();
String getData1 = itemList.get(i).getData1();
sectionCell = new ItemModel(date,data1); // Changed
sectionCell.setToSectionHeader();
tmpHeaderPositions.add(i + addedRow); // Edited
addedRow++; // Edited
tempList.add(sectionCell);
header = itemList.get(i).getDate();
}
tempList.add(itemList.get(i));
}
// Added this code block
tmpHeaderPositions.add(tempList.size());
for (int i = 0; i < tmpHeaderPositions.size() - 1; i++) {
sectionCell = tempList.get(tmpHeaderPositions.get(i));
sectionCell.setDate(sectionCell.getDate() + "(" +
(tmpHeaderPositions.get(i + 1) - tmpHeaderPositions.get(i) - 1) + ")");
}
return tempList;
}
Hope that helps!
You can setText later when you get the list of data and then with the help of arraylist.length() you can set the text into section.
i am using volley library for web api call and retrieving json data using for loop and setting that data on custom listview but listview only show two values of that data like if my loop run for 4 times only 2 or 4 numbered value is shown on listview .
Below is my code for fetching values from json data.
details=new ArrayList();
depart_adapter = new Result_dep_adapter(Result.this, android.R.layout.simple_list_item_2, details);
return_adapter = new Result_ret_adapter(Result.this, android.R.layout.simple_list_item_2, details);
departlist.setAdapter(depart_adapter);
returnlist.setAdapter(return_adapter);
try {
for (int k = 0; k < response.length(); k++) {
custom_result=new Custom_Result();
Log.i("response",","+ response.length());
JSONObject obj = response.getJSONObject(k);
JSONObject flight = obj.getJSONObject("Flights");
JSONArray array = flight.getJSONArray("Segments");
for (int i = 0; i < array.length(); i++) {
JSONObject depart = (JSONObject) array.get(i);
String departdate_time = depart.getString("DepartureTime");
String arrivedate_time = depart.getString("ArrivalTime");
Boolean returnflight=depart.getBoolean("IsReturnFlight");
duration=depart.getString("FlightDuration");
Log.i("segments",","+returnflight);
JSONObject Airline=depart.getJSONObject("Airline");
String Airline_code=Airline.getString("Name");
JSONObject Airlinename=depart.getJSONObject("MarketingCarrier");
String name=Airlinename.getString("Name");
Log.i("Airline code", Airline_code);
String[] departtime = departdate_time.split("T");
String[] arrivetime = arrivedate_time.split("T");
if (!returnflight) {
String ddate = departtime[0];
String dtime = departtime[1].substring(0, 5);
Log.i("time", dtime);
String duration = depart.getString("FlightDuration");
String Adate = arrivetime[0];
String Atime = arrivetime[1].substring(0, 5);
custom_result.setDepart_date(ddate);
custom_result.setDepart_time(dtime);
custom_result.setArrive_date(Adate);
custom_result.setArrive_time(Atime);
custom_result.setDep_duration(duration);
custom_result.setDep_Airline_name(name);
custom_result.setDep_Airline_code(Airline_code);
}else{
String Rdate = departtime[0];
String Rtime = departtime[1].substring(0, 5);//return depart time
Log.i("time", Rtime);
String return_duration = depart.getString("FlightDuration");
String ARdate = arrivetime[0];
String ARtime = arrivetime[1].substring(0, 5);
custom_result.setRet_arr_date(ARdate);
custom_result.setRet_arr_time(ARtime);
custom_result.setRet_dep_date(Rdate);
custom_result.setRet_dep_time(Rtime);
custom_result.setRet_duration(return_duration);
custom_result.setRet_Airline_name(name);
custom_result.setRet_Airline_code(Airline_code);
}
}
String stops = flight.getString("Stops");
JSONObject Fare = flight.getJSONObject("Fare");
String published_fare = Fare.getString("PublishedFare");
custom_result.setStops(stops);
custom_result.setPrice(published_fare);
details.add(custom_result);
}
I am new to android please help me ..
Thank you
This my adpater code
private class ViewHolder
{
ImageView Airline_logo;
TextView Airline_code,dep_time,dep_arr_time,dep_stops,dep_duration,
dep_price;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
// custom_result=Custom_Result.getCustom_result();
custom_result=getItem(position);
LayoutInflater inflater=(LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if(convertView==null)
{
convertView=inflater.inflate(R.layout.result_listview,null);
holder=new ViewHolder();
holder. Airline_logo=(ImageView) convertView.findViewById(R.id.dep_airlines_image);
holder.Airline_code=(TextView) convertView.findViewById(R.id.dep_airline_code);
holder.dep_time=(TextView) convertView.findViewById(R.id.dep_depart_time);
holder.dep_arr_time=(TextView) convertView.findViewById(R.id.dep_arrive_time);
holder.dep_stops=(TextView) convertView.findViewById(R.id.dep_stops_info);
holder.dep_duration=(TextView) convertView.findViewById(R.id.dep_duration);
holder.dep_price=(TextView) convertView.findViewById(R.id.dep_airline_price);
convertView.setTag(holder);
}else
{
holder=(ViewHolder)convertView.getTag();
}
String imagename=custom_result.getDep_Airline_code().toLowerCase();
String path="drawable/"+imagename;
// String logo=path.toLowerCase();
// String PACKAGE_name=getContext().getPackageName();
int imageresource=context.getResources().getIdentifier(path, null, context.getPackageName());
if(imageresource==0)
{
imageresource=R.drawable.flight_icon;
}
Drawable image=context.getResources().getDrawable(imageresource);
// holder. Airline_logo.setImageBitmap(BitmapFactory.decodeResource(getContext().getResources(),image));
holder.Airline_logo.setImageDrawable(image);
holder.Airline_code.setText(custom_result.getDep_Airline_name());
holder.dep_time.setText(custom_result.getDepart_time());
holder.dep_arr_time.setText(custom_result.getArrive_time());
holder.dep_stops.setText(custom_result.getStops());
holder.dep_duration.setText(custom_result.getDep_duration());
holder.dep_price.setText(custom_result.getPrice());
return convertView;
}
You are using android.R.layout.simple_list_item_2 as the layout for the row.
That layout only has 2 textviews so it cant show more than 2 values.
If you need to show more things you need to create your custom adapter from the BaseAdapter Class.
Then in the getView() method you can draw the row with anything you need.
Hope this helps.
I am trying to make customize array adapter that can be used for object "data"
public class theAdapter extends ArrayAdapter {
private ArrayList <listToDo> list;
public theAdapter(Context context, ArrayList<listToDo>list) {
super(context, R.layout.my_layout, list);
this.list = list;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.my_layout,parent,false);
listToDo activity = (listToDo) getItem(position);
TextView theTextView = (TextView) view.findViewById(R.id.textView);
theTextView.setText(activity.things);
CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkbox);
checkBox.setChecked(activity.checked);
return view;
}
}
However, this prints out same thing over and over again.
For instance if the ArrayList has 1,2,3,4,5. (this is not exact object I have)
It prints out 5,5,5,5,5.
EDIT---------------------------------
protected void dataRead (){
File f = new File( Environment.getExternalStorageDirectory(),"user.txt");
listToDo original = new listToDo ();
try {
FileInputStream fis = new FileInputStream(f);
InputStreamReader temp = new InputStreamReader(fis);
BufferedReader bis = new BufferedReader(temp);
String activity;
while ((activity = bis.readLine()) != null){
String[] parts = activity.split("\t");
original.things = parts[0];
if (parts[1] == "1"){
original.checked=true;
}
else{
original.checked=false;
}
data.add(original);
Log.v(TAG, original.things);
}
for (int i =0; i < data.size(); i++){
Log.d(TAG,data.get(i).things);
}
bis.close();
}
catch (Exception e) {
}
}
Explanation : the current way you are creating your list items only ever creates ONE listToDo named "original" and changes the values in it during each loop. Also in the loop you add the same original object over again for however many lines you have in user.txt. So, lets move the listToDo instance creation inside your loop so it will create a new listTodo class object named original each loop, set some values (checked and things), and then add to the data List
protected void dataRead (){
File f = new File( Environment.getExternalStorageDirectory(),"user.txt");
try {
FileInputStream fis = new FileInputStream(f);
InputStreamReader temp = new InputStreamReader(fis);
BufferedReader bis = new BufferedReader(temp);
String activity;
while ((activity = bis.readLine()) != null){
listToDo original = new listToDo ();
String[] parts = activity.split("\t");
original.things = parts[0];
if ("1".equals(parts[1])) {
original.checked=true;
}
else{
original.checked=false;
}
data.add(original);
Log.v(TAG, original.things);
}
for (int i =0; i < data.size(); i++){
Log.d(TAG,data.get(i).things);
}
bis.close();
}
catch (Exception e) {
}
}
Also, I think your adapter class is a bit off.
public class theAdapter extends ArrayAdapter<listToDo> {
public theAdapter(Context context, ArrayList<listToDo> list) {
super(context, R.layout.my_layout, list);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
listToDo activity = (listToDo) getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.my_layout, parent, false);
}
TextView theTextView = (TextView) convertView.findViewById(R.id.textView);
theTextView.setText(activity.things);
CheckBox checkBox = (CheckBox) convertView.findViewById(R.id.checkbox);
checkBox.setChecked(activity.checked);
return convertView;
}
}
Here is a full on tutorial just in case :
https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView
I want to the change the text of the button which was clicked in a getView function. The text is changed but when the view is scrolled the text of other buttons which the same id is also changed. I don't want that. I want only the text of the button which was clicked to be changed.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final int i=position;
List dialog = DialogList.get(i);
final Object memid = dialog.get(2).toString();
final String dialogid = dialog.get(3).toString();
final String dialogtype = dialog.get(4).toString();
ImageView imageViews;
if (convertView == null) {
LayoutInflater layoutInflator = LayoutInflater.from(getContext());
convertView = layoutInflator.inflate(R.layout.invite_friends_list, null);
holder = new ViewHolder();
holder.friendsname = (TextView) convertView.findViewById(R.id.friendsname);
holder.profimage = (ImageView) convertView.findViewById(R.id.member_image);
holder.assign = (Button) convertView.findViewById(R.id.btnInvite);
convertView.setTag(holder);
}
holder = (ViewHolder) convertView.getTag();
holder.friendsname.setText(user_name);
holder.assign.setTag(holder);
holder.assign.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("assigntext", holder.assign.getText().toString());
SharedPreferences prfs = _context.getSharedPreferences("MyPref",
Context.MODE_PRIVATE);
String token = prfs.getString("apptoken", "");
String url = null;
if(dialogtype.equals("V"))
{
url = "http://www.jjhjjkh.com/index.php?/alkjlkjlk/dialog/invjlkjlkjklialogmember?apptoken="
+ token + "&dialogid=" + dialogid+"&mid="+memid.toString();
}
if(dialogtype.equals("P"))
{
url = "http://www.ckjhuihiuhiu.com/index.php?/kjij/dialog/inviuhuihuihuimember?apptoken="
+ token + "&dialogid=" + dialogid+"&mid="+memid.toString();
}
List<String> urlList = new ArrayList<String>();
Log.d("cat",url.toString());
// JSON Node names
String TAG_DETAILS = "invitemembers";
String TAG_MSG = "msg";
// contacts JSONArray
JSONArray dialogpublish = null;
JSONArray dialogs = null;
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
// Log.d("cat",json.toString());
try {
dialogpublish = json.getJSONArray(TAG_DETAILS);
// Log.d("apptoken",login.toString());
for (int i = 0; i < dialogpublish.length(); i++) {
JSONObject d = dialogpublish.getJSONObject(i);
String msg = d.getString(TAG_MSG);
//dialogs = d.getJSONArray("updatedialog");
if (msg.equals("success")) {
// ViewHolder mH = (ViewHolder)view.getTag();
//Integer currentPos = view.getTag();
String mem_id= view.getTag().toString();
if(mem_id.equals(memid))
{
Toast.makeText(_context, "Member invited Succesfully",Toast.LENGTH_LONG).show();
ViewHolder mH = (ViewHolder)view.getTag();
mH.assign.setText("Invited");
}
//view.setText("Invited");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
I guess that is happenning because you are using the viewholder pattern. The viewholder pattern tends to cache views for performance optimization. try to write the adapter without using viewholder. If the list view items arent large in numbers.
Create a new HashMap in Adapter :
private HashMap<Integer, String> buttonTitleMap=new HashMap<Integer, String>();
Create a function getButtonTitle as below in Adapter :
private String getButtonTitle(int position){
if(buttonTitleMap.containsKey(position)){
return buttonTitleMap.get(position);
}else{
return "Your Normal Button text";
}
}
Then in getView() of Adapter, befor returning convertView, call :
....
holder.assign.setText(getButtonTitle(position));
holder.friendsname.setTag(position);
return convertView;
}
When the Button is clicked, you can get the list item position of the button. So what you need to do is to change the button title as you do before and also update the hashmap with the same value :
holder.assign.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
....
mH.assign.setText("Invited");
int position = (int)mH.friendsname.getTag();
buttonTitleMap.put(position,"Invited");
....
}
}
You are done.
Try
String mem_id= view.getTag().toString();
if(mem_id.equals(memid))
{
Toast.makeText(_context, "Member invited Succesfully",Toast.LENGTH_LONG).show();
((Button)view).setText("Invited");
}