Android自定义ListView刷新问题

时间:2015-08-09 00:10:01

标签: android listview android-fragments android-listview widget

我目前正在开发一款具有MainActivity和NavigationDrawer的Android应用,因此该应用的每个屏幕都实现为片段。

每个片段都在这里实例化:

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

目前我正在实施案例2.它包含一组在ListView中收集的资源,其中TextField显示货币。

下面是与ListView一起使用的apdater代码。我想唯一重要的部分是getView方法。无论如何,我发布了整个班级

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

}

我已经读过这个帖子:Android Custom Listview,但正如我所看到的那样,我的问题很明显地说明了位置/视图的逻辑。

我的问题是:如果我上下滚动,按钮上的文字加上资源的lvls开始改变。 你看到的Log.d,如果代码显示调用此方法时位置是正确的,但标记和convertView对于给定的位置是错误的。

知道为什么会这样吗?任何想法如何在没有蛮力的情况下修复它(比如重建给定位置的视图)。

提前感谢您的帮助。 :) :) :))

1 个答案:

答案 0 :(得分:0)

试试这个;

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

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


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

然后你应该处理你的改变按钮。

使用changingArray实现onChangeStateListener(应该是字段)