ListView按钮并不总是有效

时间:2014-10-12 15:00:32

标签: android

正如您所看到的,我有一个带有textviews的列表视图,按下按钮会导致电话呼叫。问题是,在选择一个列表项(总是有效)之后按下按钮会导致奇怪的行为:有时它会起作用,有时它不起作用。我已经阅读了类似的主题,但无法找到解决方案。任何帮助将不胜感激

for (i = 0; i < final_itinList.size(); i++) {
final_itinList.get(i).put("num", String.valueOf(i + 1));
String timi = final_itinList.get(i).get("diff");
final_itinList.get(i).put("diff", timi + "Km");
            }

final ListAdapter adapter = new SimpleAdapter(
CheckItineraries.this, final_itinList,
R.layout.list_item2, new String[] { "num",
"startPoliPro", "finalPoliPro", "diff" },
new int[] { R.id.number_n, R.id.startpoli,
            R.id.finalpoli, R.id.numKm });


list.setOnItemClickListener(new OnItemClickListener() {


@Override
public void onItemClick(AdapterView<?> parent,
        View container, int position, long id) {

@SuppressWarnings("unchecked")
HashMap<String, Object> obj = (HashMap<String, Object>) adapter.getItem(position-1);
                    final String phone_number = (String) obj.get("phone_number");


 Button btnphone = (Button) findViewById(R.id.btnphone);
    btnphone.setOnClickListener(new OnClickListener() {

        @Override
    public void onClick(View btnphone) {

    try {                                               
            Intent intent = new Intent(
            Intent.ACTION_CALL);
            intent.setData(Uri.parse("tel:"+phone_number));
                                startActivity(intent);
        } catch (Exception e) {
        Log.e("Demo application",
        "Failed to invoke call", e);
        }

2 个答案:

答案 0 :(得分:0)

您正在列表项侦听器中设置按钮侦听器。

这意味着:当您单击列表项时,将设置按钮单击侦听器。只有这样,您才能点击该特定按钮来调用该呼叫。


您需要做的是创建一个自定义适配器,在列表项膨胀(创建)后设置按钮侦听器。这是一个例子:

for (i = 0; i < final_itinList.size(); i++) {
    final_itinList.get(i).put("num", String.valueOf(i + 1));
    String timi = final_itinList.get(i).get("diff");
    final_itinList.get(i).put("diff", timi + "Km");
}

final ListAdapter adapter = new SimpleAdapter(
        CheckItineraries.this, final_itinList,
        R.layout.list_item2, new String[] { "num",
        "startPoliPro", "finalPoliPro", "diff" },
        new int[] { R.id.number_n, R.id.startpoli,
                R.id.finalpoli, R.id.numKm }) {
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = super.getView(position, convertView, parent);

        // Fetch the phone number (dunno why you have position-1...)
        HashMap<String, Object> obj = (HashMap<String, Object>) getItem(position-1);
        final String phone_number = (String) obj.get("phone_number");
        Log.d("phone", phone_number);

        // Set the button click listener
        Button btnphone = (Button) view.findViewById(R.id.btnphone);
        btnphone.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View btnphone) {
                try {
                    Intent intent = new Intent(Intent.ACTION_CALL);
                    intent.setData(Uri.parse("tel:" + phone_number));
                    startActivity(intent);
                } catch (Exception e) {
                    Log.e("Demo application", "Failed to invoke call", e);
                }
            }
        });

        return view;
    }
};

注意:这种重新设置按钮监听器的方式效率很低,但它应该可以工作(只要你的其他代码有效)。如果你遇到其他问题,你应该问另一个问题。

答案 1 :(得分:0)

使用ListView的代码段中有几件似乎不正确的事情。我建议调查Google I/O presentation以正确使用android中的ListView

您尝试在ListView行Item onClick事件上绑定按钮操作事件的代码段中的问题 - 这是完全错误的!您必须覆盖适配器的getView方法,并使用提供的数据集为每个行项目充气子视图。

例如:

   public class CustomAdapter extends SimpleAdapter {

    private Context context;
    private int layoutResId;

    public CustomAdapter(Context context, List<? extends Map<String, ?>> data, 
                    int resource, String[] from, int[] to) {

        super (context, data, resource, from, to);

        // hold the items
        this.context = context;
        this.layoutResId = resource;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolderItem viewHolder;
        if (converView == null) {

             // inflate the layout
             LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
             convertView = inflater.inflate(layoutResId, parent, false);

             // well set up the ViewHolder
             viewHolder = new ViewHolderItem();
             viewHolder.phoneBtn = (Button)view.findById(R.id.btnphone); 

             // store the holder with the view.
             convertView.setTag(viewHolder);    
        }
        else {
             // we've just avoided calling findViewById() on resource everytime
             // just use the viewHolder
             viewHolder = (ViewHolderItem) convertView.getTag();
        }

        // Don't know the purpose of position-1 here.
        HashMap<String, Object> data = (HashMap<String, Object>) getItem(position-1);
        if (data != null) {

            String phone_number = (String)data.get("phone_number");

            // set button action
            viewHolder.phoneBtn.setOnClickListener(new View.OnClickListener() {

               @Override
               public void onClick(View view) {
                  try {
                     Intent intent = new Intent(Intent.ACTION_CALL);
                     intent.setData(Uri.parse("tel:" + phone_number));
                     startActivity(intent);
                  } catch (Exception e) {
                     Log.e("Demo application", "Failed to invoke call", e);
                  }
              }
           }
        }
    }

    /**
     * Hold View items 
     */   
    static class ViewHolderItem {

        private Button phoneBtn;
    }
}

现在您可以创建CustomAdapter的对象并分配给ListView。

CustomAdapter adapter = new CustomAdapter(
                                    CheckItineraries.this, 
                                    final_itinList,
                                    R.layout.list_item2, 
                                    new String[] { "num", "startPoliPro", "finalPoliPro", "diff" },
                                    new int[] { R.id.number_n, R.id.startpoli, R.id.finalpoli, R.id.numKm });

// set the adapter
list.setAdapter(adapter);

注意:之前定义的ViewHolderItem是Android设计模式,可以减少查找findViewById()并提高平滑滚动的效果。您可以找到有关它的更多信息here