Is it posible to create a loop in ArrayAdapter method getView - java

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());
}
}
}

Related

Listview scrolling issue on checkbox

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.

List View loses values on scroll,and get worg position on item click

I have the below ListView with a custom adapter. I received an ArrayAdapter from service, but something wrong is happening on scroll and the values are lost.
public class AccountStatementArrayAdapter extends ArrayAdapter<ListaExtratos> {
public AccountStatementArrayAdapter(Context context, int textViewResourceId, List<ListaExtratos> listaExtratos) {
super(context, textViewResourceId, listaExtratos);
this.listaExtratos = listaExtratos;
}
#Override
public int getItemViewType(int position) {
return listaExtratos.get(position).getData() == null ? SECTION : ACCOUNT_STATEMENT_ITEM;
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getCount() {
return listaExtratos.size();
}
#Override
public ListaExtratos getItem(int position) {
return listaExtratos.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.list_item_account_statement, parent, false);
}
ListaExtratos p = getItem(position);
if (p != null && position != 0) {
TextView simpleDescriptionTextView = (TextView) v.findViewById(R.id.list_item_account_statement_simple_description_field);
TextView txtDataExtrato = (TextView) v.findViewById(R.id.txtDataExtrato);
TextView simpleValueTextView = (TextView) v.findViewById(R.id.list_item_account_statement_simple_value_field);
TextView completeDescriptionTextView = (TextView) v.findViewById(R.id.list_item_account_statement_complete_description_field);
TextView completeDateTextView = (TextView) v.findViewById(R.id.list_item_account_statement_complete_date_field);
TextView completeValueTextView = (TextView) v.findViewById(R.id.list_item_account_statement_complete_value_field);
TextView completeDocumentTextView = (TextView) v.findViewById(R.id.list_item_account_statement_complete_document_field);
TextView completeBalanceTextView = (TextView) v.findViewById(R.id.list_item_account_statement_complete_balance_field);
if(p.getHistorico() != null){
simpleDescriptionTextView.setText(p.getHistorico());
}
if(p.getValor() != null){
if ((p.getValor() != null) && (Double.parseDouble(p.getValor()) < 0)) {
simpleValueTextView.setTextColor(Color.RED);
completeValueTextView.setTextColor(Color.RED);
completeValueTextView.setText(StringUtil.getStringValueFromBigDecimal(new BigDecimal(p.getValor())));
simpleValueTextView.setText(StringUtil.getStringValueFromBigDecimal(new BigDecimal(p.getValor())));
} else {
simpleValueTextView.setTextColor(Color.BLACK);
completeValueTextView.setTextColor(Color.BLACK);
completeValueTextView.setText(StringUtil.getStringValueFromBigDecimal(new BigDecimal(p.getValor())));
simpleValueTextView.setText(StringUtil.getStringValueFromBigDecimal(new BigDecimal(p.getValor())));
}
}
if(p.getHistorico() != null)
completeDescriptionTextView.setText(p.getHistorico());
if(p.getData() != null)
completeDateTextView.setText(p.getData());
if(p.getDocto() != null)
completeDocumentTextView.setText(p.getDocto());
completeBalanceTextView.setVisibility(View.GONE);
if (!datas.contains(p.getData())) {
txtDataExtrato.setVisibility(View.VISIBLE);
txtDataExtrato.setText(DateUtil.getDataPorExtenso(DateUtil.dateFromString(p.getData(), "dd/MM/yyyy")));
datas += p.getData() + ";";
} else {
txtDataExtrato.setVisibility(View.GONE);
}
}
return v;
}
}
There are some bugs in your adapter code.
Remove check for position != 0
Add a else check as well where you set a empty text for each view.
For eg. :
Change this
if(p.getHistorico() != null){
simpleDescriptionTextView.setText(p.getHistorico());
}
to
if(p.getHistorico() != null){
simpleDescriptionTextView.setText(p.getHistorico());
}
else {
simpleDescriptionTextView.setText("");
}
These changes should solve your issue.

changes intended on one row but effects are showing in next row

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

ListView doesn't want to refresh

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);

why is my convertView == null on getView method?

I have an Activity with viewList + Custom Adapter.
I want to update the viewList on runtime (using callback when some resources are done downloading). I call the ui-thread to invoke this method:
public void refreshListIcons() {
if (categories != null) {
SettingsValue[] values = adapter.getValues();
for (int i = 0; i < values.length; i++) {
values[i].icon = ResManager
.GetSkinDrawable(categories[i].iconName + ".bin");
}
adapter.setValues(values);
mListView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
and then the adapter.getView method is called:
but why is convertView==null ?
one the first time the activity is created I understand.
But now this is my second time (runtime update).
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.settings_item, null);
}
...
}
It causes re-inflating too many times and crashes my app.
my entire adapter's code:
package com.waze.settings;
public class SettingValueAdapter extends BaseAdapter {
private SettingsValue[] values;
private LayoutInflater inflater;
public SettingValueAdapter(Context context) {
inflater = LayoutInflater.from(context);
}
public SettingsValue[] getValues() {
return values;
}
#Override
public int getCount() {
if (values == null) {
return 0;
}
return values.length;
}
#Override
public Object getItem(int arg0) {
return values==null? null : values[arg0];
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.settings_item, null);
}
SettingsValue item = values[position];
CheckedTextView name = (CheckedTextView) convertView.findViewById(R.id.itemText);
ImageView iconView = (ImageView) convertView.findViewById(R.id.itemIcon);
if (iconView != null && (item != null) && (item.icon != null)) {
iconView.setImageDrawable(item.icon);
iconView.setVisibility(View.VISIBLE);
} else {
iconView.setVisibility(View.GONE);
}
name.setText(item.display);
name.setChecked(item.isSelected);
View container = convertView.findViewById(R.id.itemContainer);
if (position == 0) {
if (position == values.length-1) {
container.setBackgroundResource(R.drawable.item_selector_single);
} else {
container.setBackgroundResource(R.drawable.item_selector_top);
}
} else {
if (position == values.length-1) {
container.setBackgroundResource(R.drawable.item_selector_bottom);
} else {
container.setBackgroundResource(R.drawable.item_selector_middle);
}
}
container.setPadding(0, 0, 0, 0);
return convertView;
}
public void setValues(SettingsValue[] values) {
this.values = values;
notifyDataSetChanged();
}
}
I guess you shouldn't set the adapter again. Instead modify your refresh method as:
public void refreshListIcons() {
if (categories != null) {
SettingsValue[] values = adapter.getValues();
for (int i = 0; i < values.length; i++) {
values[i].icon = ResManager
.GetSkinDrawable(categories[i].iconName + ".bin");
}
adapter.notifyDataSetChanged();
/*
adapter.setValues(values);
mListView.setAdapter(adapter);
adapter.notifyDataSetChanged();*/
}
}
Also add a viewHolder class in your adapter.

Categories