-2

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. :) :) :)

Community
  • 1
  • 1
  • possible duplicate of [ListView reusing views when ... I don't want it to](http://stackoverflow.com/questions/6921462/listview-reusing-views-when-i-dont-want-it-to) – Andrew Brooke Aug 09 '15 at 00:12
  • still , i'm using the concept of .setTag and .getTag and getting the wrong views for that given position. – Dário Pedro Aug 09 '15 at 00:22
  • Right, but for the items inside of each list item you need to set the default state you want in getView, otherwise they may get messed up when other list items are reused – Andrew Brooke Aug 09 '15 at 00:25
  • Yes , but the thing is that the itens inside of each list item have listeners and are dinamic . Does that mean that I have to create a secondary class just for tracking the change of values and type the information on everything in every single refresh ? – Dário Pedro Aug 09 '15 at 00:34

1 Answers1

0

Try this;

ViewHolder viewHolder= new ViewHolder();
if (convertView==nul){
    //your stuff 

    convertView.settag(viewholder);
}else{
     viewHolder= convertView.getTag(viewHolder);
}


//your code stuff
ButtonName.setText=ChangingArray[position]

And then you should handle your changing on button.

Implement onChangeStateListener with changingArray(should be field)

Kaloglu
  • 1,651
  • 1
  • 20
  • 31