I'm having issues with listview containing checkbox, when a checkbox is unchecked and when the view gets recycled, the checked checkbox becomes checked. Any help? I've seen lots of same topic but I can't seem to find an answer to my issue. Thank you.
Here's the code of getView.
public View getView(int i, View convertView, ViewGroup viewGroup) {
View mView = convertView;
String betid = mData.get(i).get("betid");
ViewHolder holder ;
ListView listview = findViewById(R.id.lvMain);
if (mView == null) {
Context context = viewGroup.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
mView = inflater.inflate(R.layout.row_layout, null,false);
holder = new ViewHolder();
holder.tx_number = (TextView) mView.findViewById(R.id.tx_number);
holder.tx_amount = (TextView) mView.findViewById(R.id.tx_amount);
holder.tx_counter = (TextView) mView.findViewById(R.id.tx_counter);
holder.checkBox = (CheckBox) mView.findViewById(R.id.checkmark);
holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
String[] b;
if (buttonView.isChecked()) {
EditText xxx = (EditText)findViewById(R.id.editText);
String amtX = xxx.getText().toString();
int toMultiply;
if(amtX.equals("")){
toMultiply = 1;
}else{
toMultiply = Integer.parseInt(amtX);
}
System.out.println(toMultiply);
String yy = editText.getText().toString().trim();
checked.add((Integer) holder.checkBox.getTag());
String item = listview.getItemAtPosition(i).toString();
String[] a = item.split(", ");
b = a[1].split("=");
String[] sep = a[0].split("=");
String betnumber = sep[1];
String betamount= b[1];
final String sorted = betnumber.chars().sorted().mapToObj(c -> Character.valueOf((char)c).toString()).collect(Collectors.joining());
if (doubleChecker(sorted)){
answer = (Integer.parseInt(betamount) * toMultiply / 3);
holder.tx_counter.setText(valueOf(answer));
}else{
if(yy.equals("")){
answer = (Integer.parseInt(betamount) * toMultiply / 6);
holder.tx_counter.setText(valueOf(answer));
}else{
answer = ((Integer.parseInt(betamount) * toMultiply - Integer.parseInt(yy)) / 6);
holder.tx_counter.setText(valueOf(answer));
}
}
holder.tx_counter.setBackgroundColor(getResources().getColor(R.color.bluelim));
holder.tx_amount.setBackgroundColor(getResources().getColor(R.color.bluelim));
holder.tx_number.setBackgroundColor(getResources().getColor(R.color.bluelim));
}
else {
holder.tx_counter.setBackgroundColor(Color.WHITE);
holder.tx_amount.setBackgroundColor(Color.WHITE);
holder.tx_number.setBackgroundColor(Color.WHITE);
holder.tx_counter.setText("0");
checked.remove((Integer) holder.checkBox.getTag());
}
}
});
holder.checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (((CheckBox) v).isChecked()) {
holder.checkBox.setChecked(true);
}else{
holder.checkBox.setChecked(false);
}
}
});
mView.setTag(holder);
holder.checkBox.setTag(i);
} else {
holder = (ViewHolder) mView.getTag();
((ViewHolder)mView.getTag()).checkBox.setTag(i);
}
if (betid != null) {
String betnumber = mData.get(i).get("betnumber");
String amountTarget = mData.get(i).get("amountTarget");
holder.tx_amount.setText(amountTarget);
holder.tx_number.setText(betnumber);
holder.tx_counter.setText("0");
}
ViewHolder holde2r = (ViewHolder) mView.getTag();
for (int k = 0; k < checked.size(); k++) {
if (checked.get(k) == i) {
holde2r.checkBox.setChecked(true);
}
else if (checked.get(k) != i) {
holde2r.checkBox.setChecked(false);
}
}
return mView;
}
private class ViewHolder {
TextView tx_number;
TextView tx_amount;
TextView tx_counter;
CheckBox checkBox;
}
}
Sorry for the long code, I just think that it is needed to place here because i dont knw what causes the issue.
Related
Confusing at it may seem, I am confused of what is happening too. I have an application in which there is a listview that displays values and when a row is pressed, the third value of the row will display a value.
Example is: third value is 30 and when it's pressed, it should be divided by 6, so the answer should be 5.
But when I scroll in the listview, the checkbox becomes unchecked and the third value of the row goes back to its old value (30).
Is there any way to keep the checkbox from being checked and the value of the row preserved when clicked?
Here's the snippet of my code.
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
CheckBox checkBox = (CheckBox)view.findViewById(R.id.checkmark);
TextView tv3 = (TextView)view.findViewById(R.id.tx_counter);
EditText editText = (EditText)findViewById(R.id.editText3);
String yy = editText.getText().toString().trim();
String shitts = listView.getItemAtPosition(position).toString();
try {
String[] a = shitts.split(", ");
String[] b = a[1].split("=");
String[] sep = a[0].split("=");
String betnumber = sep[1];
String betamount= b[1];
if (view != null) {
checkBox.setChecked(!checkBox.isChecked());
if(checkBox.isChecked()){
//sort number
final String sorted = betnumber.chars().sorted().mapToObj(c -> Character.valueOf((char)c).toString()).collect(Collectors.joining());
System.out.println(sorted);
//check if double digit
Boolean checker = doubleChecker(sorted);
if (checker == true){
Toast.makeText(getApplicationContext(),"DOUBLE DIGIT", LENGTH_SHORT).show();
int answer = Integer.parseInt(betamount) / 3;
tv3.setText(String.valueOf(answer));
}else{
Toast.makeText(getApplicationContext(),"NOT DOUBLE DIGIT", LENGTH_SHORT).show();
int answer;
if(yy.equals("")){
answer = Integer.parseInt(betamount) / 6;
tv3.setText(String.valueOf(answer));
}else{
answer = (Integer.parseInt(betamount) - Integer.parseInt(yy)) / 6;
tv3.setText(String.valueOf(answer));
}
}
//TODO save to array to send
}else{
//TODO mistake RETURN tv3 to old value
}
}
}catch (Exception e){
}
}
});
Here's my adapter.
class MyAdapter extends BaseAdapter {
private ArrayList<HashMap<String, String>> mData;
public MyAdapter(ArrayList<HashMap<String, String>> mData2) {
this.mData = mData2;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int i) {
return this.mData.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = getLayoutInflater().inflate(R.layout.row_layout, null);
TextView tx_number = (TextView) view.findViewById(R.id.tx_number);
TextView tx_amount = (TextView) view.findViewById(R.id.tx_amount);
TextView tx_counter = (TextView) view.findViewById(R.id.tx_counter);
String betid = mData.get(i).get("betid");
if(betid!=null){
String betnumber = mData.get(i).get("betnumber");
String amountTarget = mData.get(i).get("amountTarget");
String amountRamble = mData.get(i).get("amountRamble");
tx_number.setText(betnumber);
tx_amount.setText(amountTarget);
tx_counter.setText(amountRamble);
}
return view;
}
}
Replace your adapter code with:
public class MyAdapter extends BaseAdapter {
private ArrayList<HashMap<String, String>> mData;
public MyAdapter(ArrayList<HashMap<String, String>> mData2) {
this.mData = mData2;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public Object getItem(int i) {
return this.mData.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
View mView = convertView;
String betid = mData.get(i).get("betid");
ViewHolder holder ;
if (mView == null) {
Context context = viewGroup.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
mView = inflater.inflate(R.layout.row_layout, null,false);
holder = new ViewHolder();
holder.tx_number = (TextView) mView.findViewById(R.id.tx_number);
holder.tx_amount = (TextView) mView.findViewById(R.id.tx_amount);
holder.tx_counter = (TextView) mView.findViewById(R.id.tx_counter);
mView.setTag(holder);
} else {
holder = (ViewHolder) mView.getTag();
}
if (betid != null) {
String betnumber = mData.get(i).get("betnumber");
String amountTarget = mData.get(i).get("amountTarget");
String amountRamble = mData.get(i).get("amountRamble");
holder.tx_number.setText(betnumber);
holder.tx_amount.setText(amountTarget);
holder.tx_counter.setText(amountRamble);
}
return mView;
}
private static class ViewHolder {
TextView tx_number;
TextView tx_amount;
TextView tx_counter;
}
}
I added new code with ViewHolder.
hi friends i am not able to understand how to set text in the same row of the list view where i am having two button with text view at the center but when i am trying to increment or decrement the effect is showing on the next row but not the row on which i want the changes to be applied
CartAdapter.java
public class Cart_Adapter extends BaseAdapter {
Context cartcontext;
List<MobiData> cartlist;
LayoutInflater inflater;
cartlist cartdata;
public ArrayList<Integer> quantity = new ArrayList<Integer>();
CustomButtonListener customButtonListener;
public Cart_Adapter(Context cartcontext, List<MobiData> cartlist) {
this.cartcontext = cartcontext;
this.cartlist = cartlist;
}
#Override
public int getCount() {
return cartlist.size();
}
#Override
public Object getItem(int position) {
return cartlist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
inflater = (LayoutInflater) cartcontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
cartdata = new cartlist();
convertView = inflater.inflate(R.layout.cart_row, parent, false);
cartdata.decrement = (TextView) convertView.findViewById(R.id.decrement);
cartdata.single = (TextView) convertView.findViewById(R.id.single);
cartdata.single.setTag(position);
cartdata.increment = (TextView) convertView.findViewById(R.id.increment);
cartdata.increment.setTag(position);
cartdata.cancel = (TextView) convertView.findViewById(R.id.cancel);
cartdata.vcmedname = (TextView) convertView.findViewById(R.id.vcmedname);
cartdata.vcmedprice = (TextView) convertView.findViewById(R.id.vcmedprice);
Typeface carttext = Typeface.createFromAsset(cartcontext.getAssets(), "fonts/fontawesome.ttf");
cartdata.decrement.setTypeface(carttext);
cartdata.increment.setTypeface(carttext);
cartdata.cancel.setTypeface(carttext);
convertView.setTag(cartdata);
} else {
cartdata = (cartlist) convertView.getTag();
}
MobiData newcart = cartlist.get(position);
cartdata.vcmedname.setText(newcart.getVcmedname());
cartdata.vcmedprice.setText(newcart.getVcmedprice());
cartdata.single.setText(newcart.getVcqty());
final String cartids = newcart.getVcmedid();
cartdata.cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cartlist.remove(position);
notifyDataSetChanged();
}
});
cartdata.increment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick( View v) {
if (customButtonListener !=null){
int plus = Integer.parseInt(cartdata.single.getText().toString());
plus++;
int plus = Integer.parseInt(cartdata.single.getText().toString());
plus++;
cartdata.single.setText(String.valueOf(plus));
SharedPreferences viewpref = cartcontext.getSharedPreferences("datapref", Context.MODE_PRIVATE);
String cartuid = viewpref.getString("uid", "");
String carttempid = viewpref.getString("tempid", "");
String incremnturl = "http://sampletemplates.net/mobichemist/json/cart_process.php?mid=" + cartids + "&userid=" + cartuid + "&tempid=" + carttempid;
Log.d("Incremnturl", incremnturl);
JsonArrayRequest incrementarray = new JsonArrayRequest(Request.Method.GET, incremnturl, (String) null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++) {
try {
JSONObject incrobj = response.getJSONObject(i);
int plus = Integer.parseInt(cartdata.single.getText().toString());
plus++;
cartdata.single.setText(String.valueOf(plus));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Incrementurl", String.valueOf(error));
}
});
incrementarray.setRetryPolicy(new DefaultRetryPolicy(50000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
AppController.getInstance().addToRequestQueue(incrementarray);
}
});
cartdata.decrement.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int i = Integer.parseInt(cartdata.single.getText().toString());
i--;
if (i <= 0) {
Toast.makeText(Single_Cart_Page.this, "Minimum Quantity is 1", Toast.LENGTH_SHORT).show();
} else {
cartdata.single.setText(String.valueOf(i));
}
}
});
return convertView;
}
static class cartlist {
TextView decrement, single, increment, cancel, vcmedname, vcmedprice;
}
try this and add your other code.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.cart_row, parent, false);
holder = new ViewHolder();
holder.decrement = (TextView) convertView.findViewById(R.id.decrement);
holder.single = (TextView) convertView.findViewById(R.id.single);
holder.increment = (TextView) convertView.findViewById(R.id.increment);
holder.cancel = (TextView) convertView.findViewById(R.id.cancel);
holder.vcmedname = (TextView) convertView.findViewById(R.id.vcmedname);
holder.vcmedprice = (TextView) convertView.findViewById(R.id.vcmedprice);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
Typeface carttext = Typeface.createFromAsset(cartcontext.getAssets(), "fonts/fontawesome.ttf");
holder.decrement.setTypeface(carttext);
holder.increment.setTypeface(carttext);
holder.cancel.setTypeface(carttext);
MobiData newcart = cartlist.get(position);
holder.vcmedname.setText(newcart.getVcmedname());
holder.vcmedprice.setText(newcart.getVcmedprice());
holder.single.setText(newcart.getVcqty());
final String cartids = newcart.getVcmedid();
holder.cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cartlist.remove(position);
notifyDataSetChanged();
}
});
return convertView;
}
static class ViewHolder {
private TextView decrement;
private TextView single;
private TextView increment;
private TextView vcmedname;
private TextView vcmedprice;
}
Use ArrayAdaper instead of Base Adapter with ViewHolder. Don't set setTag(position) manually for all views.
Find ViewHolder example here https://dzone.com/articles/optimizing-your-listview .It will solve your indexing problem. ViewHolder class sets all views position. Also find more description on Hold View Objects in a View Holder
I have one problem, I have one activity and one dialogfragment. When I click on button in my dialogfragment I send model to Activity and write this model to the list. But when I add to the list more than one element, my listview duplicate first element, I init my adapter in onCreate() and add new information in onExcerciseAdd:
Activity:
public class AddTrainingActivity extends ActionBarActivity implements ExcercisesFragment.onButtonAdd {
private ActionBarDrawerToggle toggle;
int DIALOG_TIME = 1;
int myHour = 00;
int myMinute = 00;
TextView tvTime;
Button btn_add_ex;
ListView list;
ExcerciseAdapter adapter;
ArrayList<ExcerciseModel> excercise_list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_addtraining);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tvTime = (TextView) findViewById(R.id.tv_time_add);
tvTime.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showDialog(DIALOG_TIME);
}
});
btn_add_ex = (Button) findViewById(R.id.btn_add_exercise);
list = (ListView) findViewById(R.id.list_excercise);
excercise_list = new ArrayList<ExcerciseModel>();
Log.d("onCreate", "Work!");
adapter = new ExcerciseAdapter(excercise_list, this);
btn_add_ex.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ExcercisesFragment dlg = new ExcercisesFragment();
dlg.show(getSupportFragmentManager(),"dlg");
}
});
}
protected Dialog onCreateDialog(int id) {
if (id == DIALOG_TIME) {
Calendar c = Calendar.getInstance();
myHour = c.getTime().getHours();
myMinute = c.getTime().getMinutes();
TimePickerDialog tpd = new TimePickerDialog(this, myCallBack, myHour, myMinute, true);
return tpd;
}
return super.onCreateDialog(id);
}
TimePickerDialog.OnTimeSetListener myCallBack = new TimePickerDialog.OnTimeSetListener() {
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
myHour = hourOfDay;
myMinute = minute;
if (myMinute < 10) {
tvTime.setText(myHour + " : 0" + myMinute );
} else {
tvTime.setText(myHour + " : " + myMinute );
}
Log.d("TIME", "minutes " + myMinute);
}
};
#Override
public void onExcerciseAdd(ExcerciseModel model) {
Log.d("Adapter", "null? " + (adapter.isEmpty()));
excercise_list.add(model);
if (adapter.isEmpty()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
adapter.notifyDataSetInvalidated();
adapter.notifyDataSetChanged();
list.invalidate();
list.invalidateViews();
}
});
}
list.setAdapter(adapter);
for (int i = 0; i < excercise_list.size(); i++){
Log.d("List_ex", "list(" + i +"): " + excercise_list.get(i).getTitle().toString());
}
}
}
Dialogfragment:
public class ExcercisesFragment extends DialogFragment {
private Button btn_add_dialog;
private EditText edit_time;
private EditText edit_count1;
private EditText edit_count2;
private EditText edit_weight;
private AutoCompleteTextView edit_ex;
public interface onButtonAdd {
void onExcerciseAdd (ExcerciseModel model);
}
onButtonAdd button_add;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getDialog().setTitle("Title!");
View v = inflater.inflate(R.layout.fragment_add_excersise, null);
btn_add_dialog = (Button) v.findViewById(R.id.btn_add_exercise_fr);
edit_time = (EditText) v.findViewById(R.id.edit_ex_go);
edit_count1 = (EditText) v.findViewById(R.id.edit_podh);
edit_count2 = (EditText) v.findViewById(R.id.edit_repeat);
edit_weight = (EditText) v.findViewById(R.id.edit_weight_add);
edit_ex = (AutoCompleteTextView) v.findViewById(R.id.excercise_title);
button_add = (onButtonAdd) getActivity();
Resources res = getResources();
String[] excersices = res.getStringArray(R.array.excersices);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
R.layout.profile_item, R.id.item_autotext, excersices);
adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
edit_ex.setAdapter(adapter);
edit_ex.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
// Just ignore the [Enter] key
return true;
}
// Handle all other keys in the default way
return false;
}
});
edit_ex.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
edit_ex.showDropDown();
}
});
btn_add_dialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String time = edit_time.getText().toString();
String title = edit_ex.getText().toString();
String weight = edit_weight.getText().toString();
String count1 = edit_count1.getText().toString();
String count2 = edit_count2.getText().toString();
if (title.equals("") || count1.equals("") || count2.equals("") || weight.equals("") || time.equals("")) {
Toast.makeText(getActivity(),"Необходимо заполнить все поля", Toast.LENGTH_SHORT).show();
} else {
ExcerciseModel model = new ExcerciseModel();
model.setTitle(edit_ex.getText().toString());
model.setTime(Integer.parseInt(edit_time.getText().toString()));
model.setPodh(Integer.parseInt(edit_count1.getText().toString()));
model.setCount(Integer.parseInt(edit_count2.getText().toString()));
model.setWeight(Integer.parseInt(edit_weight.getText().toString()));
button_add.onExcerciseAdd(model);
dismiss();
}
}
});
return v;
}
}
and Adapter:
public class ExcerciseAdapter extends BaseAdapter {
ArrayList<ExcerciseModel> list;
Activity context;
public ExcerciseAdapter (ArrayList<ExcerciseModel> list, Activity context) {
this.list = list;
this.context = context;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtViewTitle;
TextView txtViewTime;
TextView txtViewPodh;
TextView txtViewCount;
TextView txtViewWeight;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
LayoutInflater inflater = context.getLayoutInflater();
Log.d("ConvertView", "convertview is null " + (convertView == null));
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item_ex, null);
holder = new ViewHolder();
holder.txtViewTitle = (TextView) convertView.findViewById(R.id.tv_adapter_title);
holder.txtViewTime = (TextView) convertView.findViewById(R.id.tv_adapter_time_get);
holder.txtViewPodh = (TextView) convertView.findViewById(R.id.tv_adapter_podh_get);
holder.txtViewCount = (TextView) convertView.findViewById(R.id.tv_adapter_count_get);
holder.txtViewWeight = (TextView) convertView.findViewById(R.id.tv_adapter_weight_get);
holder.txtViewTitle.setText(list.get(position).getTitle().toString());
holder.txtViewTime.setText(String.valueOf(list.get(position).getTime()));
holder.txtViewPodh.setText(String.valueOf(list.get(position).getPodh()));
holder.txtViewCount.setText(String.valueOf(list.get(position).getCount()));
holder.txtViewWeight.setText(String.valueOf(list.get(position).getWeight()));
} else {
holder = (ViewHolder) convertView.getTag();
}
Log.d("Adapter", "List_size = " +list.size());
Log.d("Adapter", "Title(" + position + "): " + list.get(position).getTitle().toString());
return convertView;
}
}
I don't know, but Adatper calls too many times, when I add one element it's calls 3 times. Please help me with this problem.
You only update your list items when you are creating them. You should do something like this:
LayoutInflater inflater = context.getLayoutInflater();
View view = (convertView == null)? inflater.inflate(R.layout.list_item_ex, parent, false) : convertView;
holder = new ViewHolder();
holder.txtViewTitle = (TextView) convertView.findViewById(R.id.tv_adapter_title);
holder.txtViewTime = (TextView) convertView.findViewById(R.id.tv_adapter_time_get);
holder.txtViewPodh = (TextView) convertView.findViewById(R.id.tv_adapter_podh_get);
holder.txtViewCount = (TextView) convertView.findViewById(R.id.tv_adapter_count_get);
holder.txtViewWeight = (TextView) convertView.findViewById(R.id.tv_adapter_weight_get);
holder.txtViewTitle.setText(list.get(position).getTitle().toString());
holder.txtViewTime.setText(String.valueOf(list.get(position).getTime()));
holder.txtViewPodh.setText(String.valueOf(list.get(position).getPodh()));
holder.txtViewCount.setText(String.valueOf(list.get(position).getCount()));
holder.txtViewWeight.setText(String.valueOf(list.get(position).getWeight()));
return view;
Also you don't need to call all of these methods when changing the data set
adapter.notifyDataSetInvalidated();
adapter.notifyDataSetChanged();
list.invalidate();
list.invalidateViews();
Calling adapter.notifyDataSetChanged(); should be enough
You also don't need to reset the adapter every time you change the data, so this line can also be removed
list.setAdapter(adapter);
I have a silly question, here is my LevelsAdapter class for LinearLayout. I use it to display levels in my activity. In getView method I use "if(level.getLevel() == 1)" to get level ID, I want to ask if it is possible to create a loop in order to do that? It would be bad with my implementation if there was 100 levels or more to check.
private class LevelsAdapter extends ArrayAdapter<Level> {
private ArrayList<Level> levelsList;
public LevelsAdapter(Context context, int textViewResourceId,ArrayList<Level> levelsList) {
super(context, textViewResourceId, levelsList);
this.levelsList = new ArrayList<Level>();
this.levelsList.addAll(levelsList);
}
private class ViewHolder {
TextView level;
TextView levelQuestionsCount;
TextView lockedLevelContainer;
Button start;
RelativeLayout levelLayout;
LinearLayout levelLayoutInner;
LinearLayout unlockedLevelContainer;
ImageView locklevel;
}
private void unlock(ViewHolder holder){
holder.lockedLevelContainer.setVisibility(View.GONE);
holder.locklevel.setVisibility(View.GONE);
}
private void lock(ViewHolder holder, int toUnlock){
holder.unlockedLevelContainer.setVisibility(View.GONE);
holder.lockedLevelContainer.setVisibility(View.VISIBLE);
holder.lockedLevelContainer.setText("Level is locked. Answer "+ (toUnlock - countSolved) +" questions to unclock.");
holder.locklevel.setVisibility(View.VISIBLE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.level1, null);
holder = new ViewHolder();
holder.level = (TextView) convertView.findViewById(R.id.level);
holder.levelQuestionsCount = (TextView) convertView.findViewById(R.id.levelQuestionsCount);
holder.lockedLevelContainer = (TextView) convertView.findViewById(R.id.lockedLevelContainer);
holder.start = (Button) convertView.findViewById(R.id.buttonLevel);
holder.levelLayout = (RelativeLayout) convertView.findViewById(R.id.levelLayout);
holder.levelLayoutInner = (LinearLayout) convertView.findViewById(R.id.levelLayoutInner);
holder.unlockedLevelContainer = (LinearLayout) convertView.findViewById(R.id.unlockedLevelContainer);
holder.locklevel = (ImageView) convertView.findViewById(R.id.locklevel);
convertView.setTag(holder);
holder.start.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
D.sh("Clicked");
Button start = (Button) v;
Level level = (Level) start.getTag();
Intent dialogIntent = new Intent(MainActivity.this, LevelActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
dialogIntent.putExtra("level", level.getLevel());
MainActivity.this.startActivity(dialogIntent);
}
});
} else {
holder = (ViewHolder) convertView.getTag();
}
Level level = levelsList.get(position);
holder.levelLayoutInner.setBackgroundResource(R.drawable.bg_level_repeat);
if(level.getLevel() == 1) {
holder.levelLayout.setBackgroundResource(R.drawable.level1_button);
if(countSolved >= Level.L1_TO_UNLOCK){
unlock(holder);
} else {
lock(holder, Level.L1_TO_UNLOCK);
}
}
if(level.getLevel() == 2) {
holder.levelLayout.setBackgroundResource(R.drawable.level2_button);
if(countSolved >= Level.L2_TO_UNLOCK){
unlock(holder);
} else {
lock(holder, Level.L2_TO_UNLOCK);
}
}
if(level.getLevel() == 3) {
holder.levelLayout.setBackgroundResource(R.drawable.level3_button);
if(countSolved >= Level.L3_TO_UNLOCK){
unlock(holder);
} else {
lock(holder, Level.L3_TO_UNLOCK);
}
}
if(level.getLevel() == 4) {
holder.levelLayout.setBackgroundResource(R.drawable.level4_button);
if(countSolved >= Level.L4_TO_UNLOCK){
unlock(holder);
} else {
lock(holder, Level.L4_TO_UNLOCK);
}
}
if(level.getLevel() == 5) {
holder.levelLayout.setBackgroundResource(R.drawable.level5_button);
if(countSolved >= Level.L5_TO_UNLOCK){
unlock(holder);
} else {
lock(holder, Level.L5_TO_UNLOCK);
}
}
holder.level.setText("Level "+level.getLevel());
holder.levelQuestionsCount.setText(level.getSolved() + "/" + level.getTotal());
holder.level.setTag(level);
holder.start.setTag(level);
return convertView;
}
}
njzk2, I used your idea.
for (int i=1;i<=5;i++) {
if(level.getLevel() == i) {
int resID = getResources().getIdentifier("level" + i + "_button" , "drawable", getPackageName());
holder.levelLayout.setBackgroundResource(resID);
if(countSolved >= level.getToUnlock()){
unlock(holder);
} else {
lock(holder, level.getToUnlock());
}
}
}
I am making a custom list and I want to save the text of some TextFile which is in R.id.quantity.
I also want to save the state of a checkbox. I tried to manage checked state of a checkbox in a list.
The List contains other view controls. I have put them in a Viewholder class. I am initializing qtyTxtV with some initial array value, once an event occurs in this code the value of the array changes but the list contents gets erased. Please help out.
Now this code is giving me a null pointer exception:
class MyAdapter1 extends BaseAdapter {
Context context;
ArrayList<Integer> price = new ArrayList<Integer>();
ArrayList<String> names = new ArrayList<String>();
public static HashMap<Integer, String> myList = new HashMap<Integer, String>();
static class ViewHolder {
public TextView tvQuantityName, tvPrice, tvDishName;
public ImageView imv1, imv2, imv3, imv4, imv5;
public EditText edtQty;
public CheckBox chkAdd;
}
public MyAdapter1(VegDetail vegDetail, ArrayList<String> names2,
ArrayList<Integer> price2) {
this.context = vegDetail;
this.names = names2;
this.price = price2;
}
#Override
public int getCount() {
return names.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#SuppressWarnings("null")
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
// View row = inflater.inflate(R.layout.rowlayout, parent, false);
if (row == null) {
LayoutInflater inflater = LayoutInflater.from(context);
row = inflater.inflate(R.layout.rowlayout, parent, false);
holder.edtQty = (EditText) row.findViewById(R.id.quantity);
holder.imv1 = (ImageView) row.findViewById(R.id.star1);
holder.imv2 = (ImageView) row.findViewById(R.id.star2);
holder.imv3 = (ImageView) row.findViewById(R.id.star3);
holder.imv4 = (ImageView) row.findViewById(R.id.star4);
holder.imv5 = (ImageView) row.findViewById(R.id.star5);
holder.tvDishName = (TextView) row.findViewById(R.id.item_name);
holder.tvPrice = (TextView) row.findViewById(R.id.price1);
holder.tvQuantityName = (TextView) row.findViewById(R.id.qtyTxtV);
holder.chkAdd = (CheckBox) row.findViewById(R.id.chkAdd);
EditText edtQty = (EditText) row.findViewById(R.id.quantity);
edtQty.setText(VegDetail.qtyArray[position].toString());
CheckBox chkAdd = (CheckBox) row.findViewById(R.id.chkAdd);
chkAdd.setSelected(VegDetail.chkArray[position]);
holder.edtQty.addTextChangedListener(new TextWatcher() {
public void onTextChanged(final CharSequence s,
final int start, final int before, final int count) {
}
public void afterTextChanged(final Editable s) {
int newValue;
final String boxContents = s.toString();
if (!boxContents.isEmpty()) {
try {
newValue = Integer.parseInt(boxContents);
VegDetail.qtyArray[position] = newValue;
} catch (final Exception exc) {
VegDetail.qtyArray[position] = 0;
} finally {
}
} else {
VegDetail.qtyArray[position] = 0;
}
}
public void beforeTextChanged(final CharSequence s,
final int start, final int count, final int after) {
}
});
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
CheckBox chkAdd=(CheckBox)row.findViewById(R.id.chkAdd);
chkAdd.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
//VegDetail is another class where I gonna use checked list's states
VegDetail.chkArray[position] = isChecked;
}
});
final TextView tv1 = (TextView) row.findViewById(R.id.item_name);
TextView tv2 = (TextView) row.findViewById(R.id.price1);
final TextView tvQty = (TextView) row.findViewById(R.id.quantity);
tv1.setText(names.get(position));
tv1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context,
"itme name is=>" + tv1.getText().toString(),
Toast.LENGTH_LONG).show();
}
});
tv2.setText("Rs:" + price.get(position));
return row;
}
}
The NPE must be at line :
holder.edtQty = (EditText) row.findViewById(R.id.quantity);
since holder is NULL as you have just defined above...ViewHolder holder = null