I'm currently working on an Android app that has MainActivity a NavigationDrawer, so each screen of the app is implemented as a Fragment.
Each fragment is instantiated here:
public class PlaceholderFragment extends Fragment {
private final String TAG = "Dhemage";
public TextView curr_money_txt;
public PlaceholderFragment() {
}
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
int sectionNumber = this.getArguments().getInt(ARG_SECTION_NUMBER);
View rootView;
switch (sectionNumber) {
case 1:
rootView = inflater.inflate(R.layout.home, container, false);
break;
case 2:
rootView = inflater.inflate(R.layout.activity_recursos, container, false);
/*CREATE Money TXT*/
curr_money_txt = (TextView) rootView.findViewById(R.id.curr_money_text);
curr_money_txt.setText(((navigation_bar) getActivity()).START_MONEY);
/*CREATE LIST VIEW*/
List<String> nomes_recursos = Arrays.asList("Iron", "Silver", "Gold", "Painite", "Benitoite", "Deuterium");
ListAdapter recursosAdapter = new Recurso_ListViewItens(getActivity(), R.layout.recurso_box_fragment, nomes_recursos);
ListView recursos_ListView = (ListView) rootView.findViewById(R.id.recursos_listview);
recursos_ListView.setAdapter(recursosAdapter);
break;
case 3:
rootView = inflater.inflate(R.layout.fragment_navigation_bar, container, false);
break;
default:
rootView = inflater.inflate(R.layout.fragment_navigation_bar, container, false);
break;
}
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((navigation_bar) activity).onSectionAttached(getArguments().getInt(ARG_SECTION_NUMBER));
}
}
At the moment I'm implementing the case 2. It consist in a group of a resources gathered in a ListView with a TextField showing currency on top.
The apdater code that works with the ListView is below. I guess the only important part is the getView method . Anyway I posted the entire class
public class Recurso_ListViewItens extends ArrayAdapter<String> {
private int layout;
private Context context;
public Recurso_ListViewItens(Context _context, int resource, List<String> objects) {
super(_context, resource, objects);
layout = resource;
this.context = _context;
}
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
// reuse views
if (convertView == null) {
//Inflate View
LayoutInflater fragmentInflater = LayoutInflater.from(getContext());
convertView = fragmentInflater.inflate(R.layout.recurso_box_fragment, parent, false);
//Create the viewHolder
final ViewHolder viewHolder = new ViewHolder();
//configure the viewholder
viewHolder.textoPreco = (TextView) convertView.findViewById(R.id.countdown);
viewHolder.texto_level_recurso = (TextView) convertView.findViewById(R.id.level_of_resource);
viewHolder.imageRecurso = (ImageView) convertView.findViewById(R.id.imagem_recurso);
viewHolder.getmoneyButton = (Button) convertView.findViewById(R.id.button_recurso_fragment);
viewHolder.upgradeButton = (Button) convertView.findViewById(R.id.upg_butt_recurso_fragment);
viewHolder.curr_money_link = (TextView) ((navigation_bar) getContext()).findViewById(R.id.curr_money_text);
//UPGRADE BUTTON
viewHolder.upgradeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
upg_button_action(viewHolder,position);
}
});
//GET MONEY
viewHolder.getmoneyButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getmoney_action(viewHolder,position);
}
});
//set tag
convertView.setTag(viewHolder);
Log.d("Dhemage","Entered if: position="+position+" tag="+convertView.getTag().toString()+"\n");
}
Log.d("Dhemage","Entered if: position="+position+" tag="+convertView.getTag().toString()+"\n");
//fill data
final ViewHolder holder = (ViewHolder) convertView.getTag();
holder.initial_variable_set(position);
switch (position) {
case 0: holder.imageRecurso.setImageResource(R.mipmap.resource_iron);break;
case 1: holder.imageRecurso.setImageResource(R.mipmap.resource_silver);break;
case 2: holder.imageRecurso.setImageResource(R.mipmap.resource_gold);break;
case 3: holder.imageRecurso.setImageResource(R.mipmap.resource_painite);break;
case 4: holder.imageRecurso.setImageResource(R.mipmap.resource_benitoite);break;
case 5: holder.imageRecurso.setImageResource(R.mipmap.resource_deuterium);break;
}
return convertView;
}
public class ViewHolder {
//WIDGETS ON FRAGMENT
TextView textoPreco;
TextView texto_level_recurso;
ImageView imageRecurso;
Button getmoneyButton;
Button upgradeButton;
TextView curr_money_link;
boolean initial_set_required = true;
public void initial_variable_set(int position) {
if(initial_set_required) {
//SET initial INFORMATION ON WIDGET
this.texto_level_recurso.setId(position);
this.upgradeButton.setText("1");
this.getmoneyButton.setText(getItem(position));// getItem(position) = mineral name
this.initial_set_required = false;
}
}
}
private void getmoney_action(ViewHolder viewHolder, int position) {
//get resource level
String niveltxt = viewHolder.texto_level_recurso.getText().toString();
int level = Integer.parseInt(niveltxt);
//get money on click
int money_to_add = money_per_click(level, position);
//get current money
int curr_money = getCurrentMoney(viewHolder);
//sets money value
curr_money+=money_to_add;
viewHolder.curr_money_link.setText(String.valueOf(curr_money));
}
private int money_per_click(int level, int position) {
int next_price;
switch (position) {
case 0:
next_price = (int) (level + 1);
break;
case 1:
next_price = (int) (level * 1.8 + 1);
break;
case 2:
next_price = (int) (level * 2.5);
break;
case 3:
next_price = (int) (level * 3);
break;
case 4:
next_price = (int) (level * 4.5);
break;
case 5:
next_price = (int) (level * 8);
break;
default:
return 0;
}
return next_price;
}
private boolean upg_button_action(ViewHolder viewHolder,int position){
//gets ugrade price
String precotxt = viewHolder.upgradeButton.getText().toString();
int curr_upg_price = Integer.parseInt(precotxt);
//get current money
int curr_money = getCurrentMoney(viewHolder);
//check if got money to pay
if (curr_money > curr_upg_price) {
//pays the upgrade
curr_money = curr_money - curr_upg_price;
viewHolder.curr_money_link.setText(String.valueOf(curr_money));
//level icon increments
String niveltxt = viewHolder.texto_level_recurso.getText().toString();
int lvl = Integer.parseInt(niveltxt);
lvl++;
viewHolder.texto_level_recurso.setText(String.valueOf(lvl));
//increses price of upgrade
int next_price = next_upgrade_price(position, curr_upg_price);
viewHolder.upgradeButton.setText(String.valueOf(next_price));
return true;
}
return false;
}
private int object_text_to_int(Button object){
//gets ugrade price
String object_text = object.getText().toString();
int value = Integer.parseInt(object_text);
return value ;
}
private int object_text_to_int(TextView object){
//gets ugrade price
String object_text = object.getText().toString();
int value = Integer.parseInt(object_text);
return value ;
}
//button upgrade pressed
//returns 0 if error occurs
public int next_upgrade_price(int position, int curr_price) {
int next_price;
switch (position) {
case 0:
next_price = (int) (curr_price * 1.5 + 1);
break;
case 1:
next_price = (int) (curr_price * 2 + 1);
break;
case 2:
next_price = (int) (curr_price * 2.5);
break;
case 3:
next_price = (int) (curr_price * 2.7);
break;
case 4:
next_price = (int) (curr_price * 3);
break;
case 5:
next_price = (int) (curr_price * 5);
break;
default:
return 0;
}
return next_price;
}
//get current money
private int getCurrentMoney(ViewHolder viewHolder) {
String curr_money_txt = viewHolder.curr_money_link.getText().toString();
int curr_money = Integer.parseInt(curr_money_txt);
return curr_money;
}
}
I've read this thread : Android Custom Listview , but as I see it my prolem goes agaisnt the logic about position/view explained in there.
My problem is : if I scroll up and down , the text on the buttons plus the lvls of the resource start changing. The Log.d that you see if the code showed me that the position is correct when this method is called , but the tag and the convertView is wrong for that given position.
Any idea why this happens ? Any idea how to fix it without brute force ( like rebuilding the view given the position ) .
Thanks in advance for your help. :) :) :)