2009-11-10 8 views
174

나는 목록의 모든 요소에 TextView와 두 개의 서로 다른 Button이있는 ListView입니다. 이런 식으로 뭔가 :안드로이드 : 여러 클릭 가능한 버튼이있는 ListView 요소

ListView 
-------------------- 
[Text] 
[Button 1][Button 2] 
-------------------- 
[Text] 
[Button 1][Button 2] 
-------------------- 
... (and so on) ... 

이 코드와 내가 전체 항목에 대한 OnItemClickListener를 만들 수 있습니다

listView.setOnItemClickListener(new OnItemClickListener() { 
    @Override 
    public void onItemClick(AdapterView<?> list, View view, int position, long id) { 
     Log.i(TAG, "onListItemClick: " + position); 

     } 

    } 
}); 

는 그러나, 나는 전체 항목을 클릭 할 수 싶어하지 않지만 오직 두 개의 버튼 각 목록 요소의

그래서, 어떻게 다음 매개 변수를 사용하여이 두 버튼의 OnClickListener를 구현합니까 내 질문 :

  • int button (요소의 버튼을 클릭 된) 요소가
  • int position (인 버튼 클릭이 발생하는 목록)에서

업데이트 : 아래의 내 답변에 설명 된 해결책을 발견했습니다. 이제 터치 스크린을 통해 버튼을 클릭/탭할 수 있습니다. 그러나 트랙볼로 수동으로 선택할 수는 없습니다. getView()의 버튼에 대해 .setFocusable(true)setClickable(true)을 설정하더라도 항상 전체 목록 항목을 선택하고 그 다음 항목 목록으로 직접 이동합니다.

나는 또한 내 사용자 지정 목록 어댑터에이 코드를 추가 :

@Override 
public boolean areAllItemsEnabled() { 
    return false;   
} 

@Override 
public boolean isEnabled(int position) { 
     return false; 
} 

이 더 목록 항목이 모두 더 이상에서 선택할 수 없음을 야기한다. 그러나 중첩 된 단추를 선택 가능하게 만드는 데 도움이되지 않았습니다.

누구나 아이디어가 있으십니까?

+0

그래도 필요합니까? –

+0

BaseAdapter 코드를 보면 areAllItemsEnabled() 및 isEnabled()가 true로 하드 코딩되어 모든 로직이없는 간단한 자리 표시자인 것을 알 수 있습니다. –

+0

SimpleCursorAdapter를 사용하려면 어떻게해야합니까? simplecursoradapter를 확장하는 사용자 지정 어댑터를 만들어야합니까? – oratis

답변

146

이 문제에 대한 해결책은 생각보다 쉽습니다. 사용자 정의 어댑터의 getView() 메소드에 setOnClickListener()를 추가하면됩니다. 버튼과 관련된

상관 데이터 getView()myButton.setTag()에 첨가되어야하며 I가 가이드로서 my blog에 상세한 용액을 등록한 view.getTag()

OnClickListener를 통해 액세스 될 수있다.

+10

"내 블로그"URL이 작동하지 않습니다 ... – vnshetty

+2

수정 됨. 보고 해 주셔서 감사합니다 .-) – znq

+0

curItem.url을 쿼리에서 어떻게 얻었습니까? 더 구체적으로 표현 하시겠습니까? – oratis

9

은 아마 당신은 그것을 할,하지만 당신은

ListView.setItemsCanFocus(true) 

와 지금 버튼이는 부속물의 @의 znq의 대답의 일종이다

+0

고마워요. 작동합니다 ... 시간을 절약했습니다. –

60

초점을 잡을 것입니다 ...

를 호출 할 수있는 방법을 발견했습니다

클릭 한 항목의 행 위치를 알고 싶어하고 행의 어느 뷰가 탭되었는지 알고 싶을 때가 많습니다. 이것은 태블릿 UI에서 훨씬 더 중요하게 될 것입니다.

다음과 같은 사용자 정의 어댑터와 함께이 작업을 수행 할 수 있습니다

:

는 트랙볼을 사용하여 수동으로 버튼을 선택하려면 :

myListView.setItemsCanFocus(true); 

을 그리고 비활성화 미래의 독자

private static class CustomCursorAdapter extends CursorAdapter { 

    protected ListView mListView; 

    protected static class RowViewHolder { 
     public TextView mTitle; 
     public TextView mText; 
    } 

    public CustomCursorAdapter(Activity activity) { 
     super(); 
     mListView = activity.getListView(); 
    } 

    @Override 
    public void bindView(View view, Context context, Cursor cursor) { 
     // do what you need to do 
    } 

    @Override 
    public View newView(Context context, Cursor cursor, ViewGroup parent) { 
     View view = View.inflate(context, R.layout.row_layout, null); 

     RowViewHolder holder = new RowViewHolder(); 
     holder.mTitle = (TextView) view.findViewById(R.id.Title); 
     holder.mText = (TextView) view.findViewById(R.id.Text); 

     holder.mTitle.setOnClickListener(mOnTitleClickListener); 
     holder.mText.setOnClickListener(mOnTextClickListener); 

     view.setTag(holder); 

     return view; 
    } 

    private OnClickListener mOnTitleClickListener = new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      final int position = mListView.getPositionForView((View) v.getParent()); 
      Log.v(TAG, "Title clicked, row %d", position); 
     } 
    }; 

    private OnClickListener mOnTextClickListener = new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      final int position = mListView.getPositionForView((View) v.getParent()); 
      Log.v(TAG, "Text clicked, row %d", position); 
     } 
    }; 
} 
+6

또는 이와 비슷한 ListView를 사용할 수도 있습니다. mListView = (ListView) v.getParent(). getParent(); – max4ever

+1

별도의 클래스에서 어댑터를 사용하면 위치를 어떻게 얻을 수 있습니까? 나는 LikeClickListener 내부의 위치를 ​​단순히 like_c.get (position)과 같은 것으로 사용했습니다. 어댑터의 getView 메소드의 최종 위치를 제안합니다. 그 변경을하면 lisview의 모든 항목에 대해 동일한 위치를 얻습니다. 이 문제를 해결할 수있는 방법을 제안 해주세요. – Manikandan

+0

그 이유는 getView 메소드의 position 매개 변수를 사용할 때 가장 최근에 생성되었지만 클릭 한 목록의 항목 위치를 제공하기 때문입니다. –

22

전체 목록 항목에 초점 :

myListView.setFocusable(false); 
myListView.setFocusableInTouchMode(false); 
myListView.setClickable(false); 

괜찮아요. 터치 스크린이있는 버튼을 클릭 할 수 있고 키패드를 사용하여 클릭 초점을 잡을 수도 있습니다.

+2

이 하나만 도와 줬어! 정말 고마워! – Onur

+0

감사합니다. 다른 답변을 시도해 보았습니다. 둘 다 작동하지 않습니다. –

+0

ExpandableListView는 어떤 항목입니까? 여러 항목으로 된 항목이 있습니다. 아이의 뷰를 클릭 할 수 있기를 바랍니다. 감사합니다. – twlkyao

5

가장 좋은 방법은 아니지만 잘 작동하고 모든 코드가 ArrayAdapter에 유지됩니다.

package br.com.fontolan.pessoas.arrayadapter; 

import java.util.List; 

import android.content.Context; 
import android.text.Editable; 
import android.text.TextWatcher; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.EditText; 
import android.widget.ImageView; 
import br.com.fontolan.pessoas.R; 
import br.com.fontolan.pessoas.model.Telefone; 

public class TelefoneArrayAdapter extends ArrayAdapter<Telefone> { 

private TelefoneArrayAdapter telefoneArrayAdapter = null; 
private Context context; 
private EditText tipoEditText = null; 
private EditText telefoneEditText = null; 
private ImageView deleteImageView = null; 

public TelefoneArrayAdapter(Context context, List<Telefone> values) { 
    super(context, R.layout.telefone_form, values); 
    this.telefoneArrayAdapter = this; 
    this.context = context; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View view = inflater.inflate(R.layout.telefone_form, parent, false); 

    tipoEditText = (EditText) view.findViewById(R.id.telefone_form_tipo); 
    telefoneEditText = (EditText) view.findViewById(R.id.telefone_form_telefone); 
    deleteImageView = (ImageView) view.findViewById(R.id.telefone_form_delete_image); 

    final int i = position; 
    final Telefone telefone = this.getItem(position); 
    tipoEditText.setText(telefone.getTipo()); 
    telefoneEditText.setText(telefone.getTelefone()); 

    TextWatcher tipoTextWatcher = new TextWatcher() { 
     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 
     } 

     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
     } 

     @Override 
     public void afterTextChanged(Editable s) { 
      telefoneArrayAdapter.getItem(i).setTipo(s.toString()); 
      telefoneArrayAdapter.getItem(i).setIsDirty(true); 
     } 
    }; 

    TextWatcher telefoneTextWatcher = new TextWatcher() { 
     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 
     } 

     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
     } 

     @Override 
     public void afterTextChanged(Editable s) { 
      telefoneArrayAdapter.getItem(i).setTelefone(s.toString()); 
      telefoneArrayAdapter.getItem(i).setIsDirty(true); 
     } 
    }; 

    tipoEditText.addTextChangedListener(tipoTextWatcher); 
    telefoneEditText.addTextChangedListener(telefoneTextWatcher); 

    deleteImageView.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      telefoneArrayAdapter.remove(telefone); 
     } 
    }); 

    return view; 
} 

} 
-4

이 구현을위한 플랫폼 솔루션은 긴 보도 자료에 나타나는 상황에 맞는 메뉴를 사용하지 않습니까?

질문 작성자는 상황에 맞는 메뉴를 알고 있습니까? listview에 버튼을 쌓아 올리면 성능에 영향을 미치고 UI가 복잡해지고 플랫폼에 권장되는 UI 디자인을 위반하게됩니다.

flipside; 문맥 메뉴 - 수동적 표현이없는 본성 -은 최종 사용자에게는 분명하지 않습니다. 행동을 기록하는 것을 고려해보십시오.

이 가이드는 좋은 시작을 제공합니다.

http://www.mikeplate.com/2010/01/21/show-a-context-menu-for-long-clicks-in-an-android-listview/

+0

그리고 downvote에 대한 이유는 무엇입니까? – Gusdor

12

나는 위의 사용자보다 많은 경험을 가지고 있지 않지만 나는이 같은 문제에 직면하고 내가 이벤트를

public void btnRemoveClick(View v) 
{ 
    final int position = listviewItem.getPositionForView((View) v.getParent()); 
    listItem.remove(position); 
    ItemAdapter.notifyDataSetChanged(); 

} 
+0

흥미로운 솔루션 – sherpya

2

I을 클릭 btnRemoveClick 솔루션

아래
<Button 
     android:id="@+id/btnRemove" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_toRightOf="@+id/btnEdit" 
     android:layout_weight="1" 
     android:background="@drawable/btn" 
     android:text="@string/remove" 
     android:onClick="btnRemoveClick" 
     /> 

이것을 해결 늦었지만 이것이 도움이 될 수 있음을 알았습니다. 다른 클릭 액션을 위해 맞춤형 어댑터 클래스를 작성하는 예입니다.

public class CustomAdapter extends BaseAdapter { 

    TextView title; 
    Button button1,button2; 

    public long getItemId(int position) { 
     return position; 
    } 

    public int getCount() { 
     return mAlBasicItemsnav.size(); // size of your list array 
    } 

    public Object getItem(int position) { 
     return position; 
    } 

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

     if (convertView == null) { 
      convertView = getLayoutInflater().inflate(R.layout.listnavsub_layout, null, false); // use sublayout which you want to inflate in your each list item 
     } 

     title = (TextView) convertView.findViewById(R.id.textViewnav); // see you have to find id by using convertView.findViewById 
     title.setText(mAlBasicItemsnav.get(position)); 
     button1=(Button) convertView.findViewById(R.id.button1); 
     button1.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      //your click action 

      // if you have different click action at different positions then 
      if(position==0) 
       { 
         //click action of 1st list item on button click 
     } 
      if(position==1) 
       { 
         //click action of 2st list item on button click 
     } 
    }); 

// similarly for button 2 

    button2=(Button) convertView.findViewById(R.id.button2); 
     button2.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      //your click action 

    }); 



     return convertView; 
    } 
}