单击按钮

时间:2015-07-08 17:42:59

标签: android listview android-listview listviewitem

我创建了一个列表视图,如图所示。链接:

Image

问题:我希望如果用户点击按钮+-,则当前显示0的文本视图会相应地增加或减少。但是,如果我单击第一个项目的按钮,则会在其他行中更新textview。我不知道如何实现这个。

这是代码:

public class HomePage extends Fragment {

    String[] listitems;
    int[] images = { R.drawable.cadburysilk, R.drawable.cadburys_dairymilk,
            R.drawable.perk, R.drawable.kitkat,
            R.drawable.nestlemunchchocolate, R.drawable.cadbury_bournville_bar,
            R.drawable.snickers };
    ListView list;
    DBAdapter dbadapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub

        View rootview = inflater.inflate(R.layout.activity_home_page,
                container, false);
        View view = View.inflate(getActivity(), R.layout.headerview, null);

        Resources res = getResources();
        listitems = res.getStringArray(R.array.items);
        list = (ListView) rootview.findViewById(R.id.itemslist);
        list.addHeaderView(view);
        AdapterClass adapterClass = new AdapterClass(this.getActivity(),
                listitems, images);
        list.setAdapter(adapterClass);
        return rootview;
    }

}

class AdapterClass extends ArrayAdapter<String> {
    Context context;
    int[] images;
    String[] names;
    Button add, sub;
    TextView number;
    Integer count=0;

    static class ViewHolder {
        public TextView textView;
        public ImageView imageView;

    }

    public AdapterClass(Context c, String[] items, int imgs[]) {
        // TODO Auto-generated constructor stub
        super(c, R.layout.rowlayout, R.id.quantity, items);
        this.context = c;
        this.images = imgs;
        this.names = items;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        View row = convertView;
        // reuse views

        if (row == null) {

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.rowlayout, parent, false);
            ViewHolder viewHolder = new ViewHolder();
            viewHolder.imageView = (ImageView) row.findViewById(R.id.img);
            viewHolder.textView = (TextView) row.findViewById(R.id.textView1);
            add = (Button) row.findViewById(R.id.button1);
            add.setTag(position);
            sub = (Button) row.findViewById(R.id.button2);
            sub.setTag(position);
            number = (TextView)row.findViewById(R.id.quantity);

            row.setTag(viewHolder);
        }
        ViewHolder holder = (ViewHolder) row.getTag();
        holder.imageView.setImageResource(images[position]);
        holder.textView.setText(names[position]);
        add.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                count=count+1;
                number.setText(count.toString());
            }
        });

        sub.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                count=count-1;
                number.setText(count.toString());
            }
        });
        return row;
    }



}

请帮忙。另外,我需要帮助来显示textview在下一个活动或片段中包含正数的项目。

3 个答案:

答案 0 :(得分:5)

我写了一篇简短的demo for my answer which you can see here

示例:

当您准备就绪后,您可以使用您的数据源(不是您的适配器,而不是列表视图)来查找数量为&gt;的产品。 0

    public List<Product> getBasket() {
        List<Product> basket = new ArrayList<>();
        for (Product product : productList) {
            if (product.quantity > 0) {
                basket.add(product);
            }
        }
        return basket;
    }

您的适配器有一个任务:创建/绑定视图到数据,它不需要做更多。

没有演示的初步答案:

如果直接更新项目视图,您将无法获取具有正数的所有项目,因为这些更新的值仅存储在视图中,而不是存储在某些数据结构中可以迭代

这就是不应该直接更新项目视图的原因,而是在单击加号/减号按钮时使用回调,修改基础数据集,然后调用adapter.notifyDatasetChanged()再次更新ListView / RecyclerView。

将回调传递给适配器:

public interface ItemInteraction {
    void onPlusButtonClick(long id);
    void onMinusButtonClick(long id);
}

您可以通过将其设置为相关视图上的单击侦听器的回调来使用它。 ID可以是任何内容,只要它可以唯一标识列表视图行所代表的数据项。

final long id = item.getId();
plusButtonView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick() {
        callback.onPlusButtonClick(id);
    }
});

在这个类似的问题中给出了一个例子,其中OP想要显示或隐藏一个明星(表示收藏)以获得歌曲列表here

Another explanation如何设计使用类似适配器的视图。

答案 1 :(得分:2)

按照用户370305的回答进行初始查询。

  

请帮忙。另外,我需要帮助来显示textview在下一个活动或片段中包含正数的项目。

创建一个数据结构,我正在使用HashMap,其中key是String.valueOf(position),Value是count int。

你知道密钥,因为它将从位置“0”到listitem.length。使用密钥,您可以获取计数值并检查正数。

为什么选择Hashmap:因为每次更改计数时都会覆盖新值。 (在hashmap中只维护一个唯一键)。

(position = 0,count = 0) - &gt; - 点击第0行 - &gt; (位置0,计数= -1)将在key = 0 cell上重写。

完整代码(数字增量修正并在DataStructure中设置了正值):

public class HomePage extends Fragment { 

    String[] listitems;
    int[] images = { R.drawable.cadburysilk, R.drawable.cadburys_dairymilk,
            R.drawable.perk, R.drawable.kitkat,
            R.drawable.nestlemunchchocolate, R.drawable.cadbury_bournville_bar,
            R.drawable.snickers };
    ListView list;
    DBAdapter dbadapter;

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub 

        View rootview = inflater.inflate(R.layout.activity_home_page,
                container, false);
        View view = View.inflate(getActivity(), R.layout.headerview, null);

        Resources res = getResources();
        listitems = res.getStringArray(R.array.items);
        list = (ListView) rootview.findViewById(R.id.itemslist);
        list.addHeaderView(view);
        AdapterClass adapterClass = new AdapterClass(this.getActivity(),
                listitems, images);
        list.setAdapter(adapterClass);
        return rootview;

        //You can use adapterClass.getPositiveNumber(); to retrieve all positive rows and the values!
        //Unique key will be String : 1,2,3....listitems.length. 

    } 

} 

class AdapterClass extends ArrayAdapter<String> {
    Context context;
    int[] images;
    String[] names;
    Button add, sub;
    ViewHolder holder; // Since will be accessed inside onclick

    HashMap<String,Integers> positiveNumbers = new HashMap<String,Integers>;
    Integer count=0;

    static class ViewHolder { 
        public TextView textView;
        public ImageView imageView;
        public TextView number;
        public String uniqueKey;

    } 

    public AdapterClass(Context c, String[] items, int imgs[]) {
        // TODO Auto-generated constructor stub 
        super(c, R.layout.rowlayout, R.id.quantity, items);
        this.context = c;
        this.images = imgs;
        this.names = items;
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub 
        View row = convertView;
        // reuse views 

        if (row == null) {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.rowlayout, parent, false);
            ViewHolder viewHolder = new ViewHolder();
            viewHolder.imageView = (ImageView) row.findViewById(R.id.img);
            viewHolder.textView = (TextView) row.findViewById(R.id.textView1);
            viewHolder.number = (TextView)row.findViewById(R.id.quantity);
            viewHolder.uniqueKey = String.valueOf(position);
            add = (Button) row.findViewById(R.id.button1);
            add.setTag(position);
            sub = (Button) row.findViewById(R.id.button2);
            sub.setTag(position);
            row.setTag(viewHolder);

        } 
        holder = (ViewHolder) row.getTag();  //keeping one global memory
        holder.imageView.setImageResource(images[position]);
        holder.textView.setText(names[position]);
        add.setOnClickListener(new OnClickListener() {
            @Override 
            public void onClick(View v) {
                // TODO Auto-generated method stub  
                count=count+1;
                holder.number.setText(count.toString());
                positiveNumbers.put(holder.uniqueKey,count); //Key -> String.valueOf(position) and Value -> int count
            } 
        }); 

        sub.setOnClickListener(new OnClickListener() {
            @Override 
            public void onClick(View v) {
                // TODO Auto-generated method stub 
                count=count-1;
                holder.number.setText(count.toString());
                positiveNumbers.put(holder.uniqueKey,count);   //Key -> String.valueOf(position) and Value -> int count
            } 
        }); 

        return row;
    } 


     public Map<String,Integer> getPositiveNumbers()
     {
       return positiveNumbers;
     }


}

P.S。我输入了编辑器,可能会有一些编译时错误。此外,您可以将每行的对象存储在键上,这样当您获得正数时,您可以获得任何其他参考,例如图像,我猜你需要稍后显示!

答案 2 :(得分:0)

我知道它很晚但我认为这可能有助于其他有类似问题的人

  

问题:我希望如果用户点击按钮+或 - ,当前显示为0的文本视图会相应地递增或递减。但是,如果我单击第一个项目的按钮,则会在其他行中更新textview。我不知道如何实现这一点。

查看您的代码

ViewHolder holder = (ViewHolder) row.getTag();
    holder.imageView.setImageResource(images[position]);
    holder.textView.setText(names[position]);
    add.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            count=count+1;
            number.setText(count.toString());
        }
    });

    sub.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            count=count-1;
            number.setText(count.toString());
        }
    });
    return row;

在你的ViewHolder中你设置了holder.imageview和holder.textview的值,这是我想的名字,但你忘了为holder.number设置值,你只是在onClick方法中更改它的值。 因此,当适配器创建其视图时,它找不到任何特定值,这就是它使用以前使用的视图来膨胀数据的原因。

解决方案: - 只需使用单独的列表来存储带有唯一键的号码(使用适配器位置作为键)并检查列表是否具有该键,这意味着您之前已更改了值,因此从列表中获取值并将其设置为textview如果键不存在意味着你从未更改过值,那么将textview设置为0