2014-10-12 13 views
0

Как вы можете видеть, у меня есть listview с текстовыми изображениями и нажатие кнопки вызывает телефонный звонок. Проблема в том, что после выбора элемента списка (который всегда работает) нажатие кнопки приводит к странному поведению: иногда это работает, иногда это не так. Я читал похожие темы, но не смог найти решение. Любая помощь была бы оцененаКнопка ListView не всегда работает

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

ответ

0

Есть несколько вещей, которые не кажутся правильными в вашем фрагменте кода, используя ListView. Я бы порекомендовал посмотреть Google I/O presentation для правильного использования ListView в Android.

Проблема в вашем фрагменте кода, который вы пытаетесь связать с событием действия кнопки в строке ListView. Пункт onClick событие - это совершенно неправильно! Вы должны переопределить метод адаптера getView и раздуть childview для каждого элемента строки с предоставленным набором данных.

Например:

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 определено ранее, андроид шаблон дизайна, которые снижают внешний вид окна findViewById() и увеличить производительность для плавной прокрутки. Вы можете найти больше об этом here.

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

Примечание: Этот способ повторной установки кнопки слушателя неэффективна, но тем не менее он должен работать (до тех пор, как ваш другой код работает). Если у вас возникнут дополнительные проблемы, вы должны задать другой вопрос.

+0

Я получаю сообщение об ошибке: «Локальный переменный адаптер, возможно, не был инициализирован –

+0

@FeniaKechagia обновлен, вам просто нужно удалить« адаптер ». – Simas

Смежные вопросы