2009-11-30 3 views
89

사용자 지정 ListAdapter를 사용하여 목록에 뷰를 생성하는 간단한 ListActivity가 있습니다. 일반적으로 ListAdapter는 뷰를 TextViews로 채 웁니다.하지만 지금은 버튼도 넣기를 원합니다.목록의 버튼으로 Listactivity에서 onListItemClick을 실행하는 방법은 무엇입니까?

그러나 목록 항목에 포커스 가능보기를 배치하면 목록 항목을 클릭 할 때 ListActivity에서 onListItemClick()이 실행되지 않습니다. 버튼은 여전히 ​​목록 항목 내에서 정상적으로 작동하지만 버튼 이외의 항목이 눌러지면 onListItemClick이 트리거되기를 원합니다.

어떻게하면됩니까?

+5

솔루션과의 속성 중 하나 android:focusable="false" 추가)

건배,

는 희망이 도움이 그 클릭 수 onListItem 할 것이다 별도로 u는 버튼 처리 할 수 ​​있습니다 또는하여 ImageButton을 클릭 후손 초점 성은 정말로 도움이된다. 대답으로 추가하고 받아 들여야한다! –

+0

@Max 나는 그것이 정말로 나쁜 습관, 해결 방법이기 때문에 나는 그렇지 않다. 내가 영구적 인 건강한 해결책을 발견했다면 나는 대답을 할 것이다. (만약 내가 1 년 전에이 질문을 썼다는 것을 기억한다면 :) – CodeFusionMobile

+0

나는 당신이 가지고있는 대안을보고 싶다. 나는 자손의 포커스를 설정하려고 시도 했었고 버튼으로 작동하지도 못했습니다. 또한 목록 행에 ImageViews가있는 GridView를 넣으려고했는데 비슷한 문제가 있습니다. – MrPurpleStreak

답변

59

여기에서 도와 드리겠습니다. 나는 당신이 listView 아이템을위한 커스텀 레이아웃을 가지고 있다고 가정하고,이 레이아웃은 버튼과 TextView, ImageView 등과 같은 다른 뷰로 구성되어있다. 이제 다른 버튼을 클릭하면 다른 이벤트가 발생하고 클릭 한 모든 이벤트는 다른 이벤트가 발생합니다.

ListActivity의 onListItemClick()을 사용하지 않고도이 작업을 수행 할 수 있습니다.
다음은 사용자가 수행해야하는 작업입니다.

사용자 정의 레이아웃을 사용하고 있으므로 사용자 정의 어댑터에서 getView() 메소드를 대체하려고합니다. 트릭은 버튼에 대한 다른 리스너를 설정하고 전체보기 (행)에 대해 다른 것입니다. 이 예에서 살펴 보자 :

private class MyAdapter extends ArrayAdapter<String> implements OnClickListener { 

    public MyAdapter(Context context, int resource, int textViewResourceId, 
      List<String> objects) { 
     super(context, resource, textViewResourceId, objects); 
    } 


    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     String text = getItem(position); 
     if (null == convertView) { 
      convertView = mInflater.inflate(R.layout.custom_row, null); 
     } 
     //take the Button and set listener. It will be invoked when you click the button. 
     Button btn = (Button) convertView.findViewById(R.id.button); 
     btn.setOnClickListener(this); 
     //set the text... not important  
     TextView tv = (TextView) convertView.findViewById(R.id.text); 
     tv.setText(text); 
     //!!! and this is the most important part: you are settin listener for the whole row 
     convertView.setOnClickListener(new OnItemClickListener(position)); 
     return convertView; 
    } 

    @Override 
    public void onClick(View v) { 
     Log.v(TAG, "Row button clicked"); 
    } 
} 

귀하의 OnItemClickListener 클래스가 여기에 같이 선언 될 수있다 : 물론

private class OnItemClickListener implements OnClickListener{  
    private int mPosition; 
    OnItemClickListener(int position){ 
     mPosition = position; 
    } 
    @Override 
    public void onClick(View arg0) { 
     Log.v(TAG, "onItemClick at position" + mPosition);   
    }  
} 

당신은 아마 OnItemClickListener 생성자에 좀 더 많은 매개 변수를 추가합니다.
그리고 중요한 점은 위의 getView 구현은 꽤 못 생기고, 일반적으로 findHandler 패턴을 사용하여 findViewById 호출을 피해야한다는 것입니다.하지만 이미 알고있을 것입니다.
내 custom_row.xml 파일은 버튼 "id"의 TextView, 텍스트 "id"의 ImageView 및 이미지 "id"의 ImageView를 가진 RelativeLayout입니다.
감사합니다!

+9

내 솔루션이 다른 방향으로 이동했습니다. 하위 클래스를 차단하기 위해리스트 행 레이아웃의 자손 Focusability 속성을 설정하여 갑자기 문제를 해결했습니다. 이제 이벤트 설정 및 기타 버튼과 관련된 멋진 작업을 수행하기 위해 사용자 정의 뷰 바인더가 첨부 된 simpleCursorAdapter를 사용합니다. – CodeFusionMobile

+3

이 솔루션을 사용했습니다. 그러나 경고 : onClick 처리기로 인해 목록의 내용이 변경되어 getView가 호출되는 경우 AND (ToggleButton 또는 CheckBox와 같은) 상태 도구 인 경우 AND getView가 해당 상태를 설정하면 setOnClickListener 루프 효과가 발생하지 않도록 onView에서 상태를 변경하기 전에 null을 반환하십시오. –

+0

나를 위해 일했습니다 ... – SaKet

1

ToggleButton에서 동일한 문제가 발생했습니다. 내 머리를 벽에 부딪히는 반나절 후 나는 마침내 그것을 풀었다. 'android : focusable'을 사용하여 집중 가능한 뷰를 초점을 맞추지 않는 것처럼 간단하게 만듭니다. 또한 목록 행의 포커스 가능성 및 클릭 가능성 (그냥 단어로 구성)을 사용하지 말고 기본값으로 두십시오.

물론 목록 행에서 초점을 맞출 수있는 뷰를 초점을 맞출 수 없기 때문에 키보드를 사용하는 사용자는 문제가있을 수 있습니다. 문제가되지는 않지만 100 % 완벽한 응용 프로그램을 작성하려는 경우 onItemSelected 이벤트를 사용하여 선택한 행의 요소를 포커스 가능하게 만들고 이전에 선택한 행의 요소를 초점을 맞출 수 없게 만들 수 있습니다.

+0

이 방법을 사용했습니다. 그것은 개별 항목에 집중할 수 없다는 문제를 해결할 수 있다면 가장 간단한 방법입니다. 또한 목록 항목에 대한 상태 드로어 블을 유지해야하며, 다른 대안은 그렇지 않습니다. –

18

사용자 지정 ListView에 포커스 가능 요소가 포함되어 있으면 onListItemClick이 작동하지 않습니다 (예상 된 동작이라고 생각합니다). 예를 들어

:

public class ExtendedCheckBoxListView extends LinearLayout { 

    private TextView mText; 
    private CheckBox mCheckBox; 

    public ExtendedCheckBoxListView(Context context, ExtendedCheckBox aCheckBoxifiedText) { 
     super(context); 
     … 
     mText.setFocusable(false); 
     mText.setFocusableInTouchMode(false); 

     mCheckBox.setFocusable(false); 
     mCheckBox.setFocusableInTouchMode(false); 
     …  
    } 
} 
+3

나는 당신의 해결책을 좋아한다. 행당 하나의 "클릭 가능한"위젯 만 있다면, 집중력을 부인하는 것이 우아한 해결책이다. 행의 아무 곳에서나 탭이 일치한다는 것을 의미하지만 위젯이 라디오 또는 체크 박스 인 경우 유용합니다. android : focusable = "false"android : focusableInTouchMode = "false"를 사용하여 XML에서 동일한 결과를 얻을 수 있습니다. –

+1

가시성을 변경하면 xml 방식이 작동하지 않는 것 같습니다. 따라서 "보기"를 표시로 설정 한 후에 코드를 통해 수행해야합니다. – max4ever

13

내가 같은 문제가 있습니다 : 그냥 사용자 정의보기에서 포커스를 제거, 그것은 트릭을 할 것입니다 OnListItemClick 해고하지![SOLVED]의 콘텐츠 텍스트 상자와의 ListView가있는 LinearLayout
및 행의 다른 레이아웃 (LineraLayout에 중첩 된 체크 박스 텍스트 상자)으로 중첩하는 것이 ListActivity위한 레이아웃 ListActivity,
확장 클래스 일어날

. 의

코드 :

고해상도/레이아웃/configpage.xml (ListActivity 메인)

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 
    <TextView 
     android:id="@+id/selection" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="pippo" /> 
    <ListView 
     android:id="@android:id/list" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:drawSelectorOnTop="false" 
     android:background="#aaFFaa" > 
    </ListView> 
<LinearLayout> 

res/layout/row.xml (layout for single row) 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"> 
    <CheckBox 
     android:id="@+id/img" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     **android:focusable="false"** 
     **android:focusableInTouchMode="false"** /> 

    <TextView 
     android:id="@+id/testo" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     **android:focusable="false"** 
     **android:focusableInTouchMode="false"** /> 
</LinearLayout> 

SRC /.../.../ ConfigPage.java

public class ConfigPage extends ListActivity 
{ 
    TextView selection; 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.configpage); 
     // loaded from res/value/strings 
     String[] azioni = getResources().getStringArray(R.array.ACTIONS); 
     setListAdapter(new ArrayAdapter&lt;String&gt;(this, R.layout.row, 
       R.id.testo, azioni)); 
     selection = (TextView) findViewById(R.id.selection); 
    }  

    public void onListItemClick(ListView parent, View view, int position, long id) 
    { 
     selection.setText(" " + position); 
    } 
} 

이렇게하면 row.xml에 추가 할 때 작동 시작

  • android:focusableInTouchMode="false"
  • 6,

    • android:focusable="false"
    • 은 내가 사용하는 이클립스 3.5.2
      안드로이드 SDK 10.0.1
      분 SDK 버전 :이 도움이
      희망 3

      ... 그리고 미안 내 영어에 대한 : (

    +0

    Gud 작업자 ........ 내 문제를 해결합니다. –

    +0

    @ 추수꾼은 이유를 모른다. 그러나 그것은 나를 위해 일하지 않았다. 내 onListItemClick이 호출되지 않습니다. – likejiujitsu

    +0

    android : focusable = "false"android : focusableInTouchMode = "false"코드를 추가 했습니까? – rfellons

    -1

    나는 getListAdapter를 사용했다.

    MyPojo myPojo = getListAdapter().getItem(position); 
    

    다음은 항목 내에서 적절한 값을 호출 할 myPojo에서 게터 방법을 사용하는 제품 내에서 값을 보유하는 객체를 인스턴스화) .getItem (위치).

    1
    ListView lv = getListView(); 
    lv.setTextFilterEnabled(true); 
    
    lv.setOnItemClickListener(new OnItemClickListener() { 
    public void onItemClick(AdapterView<?> parent, View view, 
        int position, long id) { 
        // When clicked, show a toast with the TextView text 
        Toast.makeText(getApplicationContext(), ((TextView) view).getText(), 
         Toast.LENGTH_SHORT).show(); 
    } 
    }); 
    
    98

    내가 previous comment 솔루션에 쓴 바와 같이하여 ImageButton에 (false)를 위해서 setFocusable이다.

    더 좋은 해결책은 목록 요소의 루트 레이아웃에 android:descendantFocusability="blocksDescendants"을 추가하는 것입니다.

    +3

    android : descendantFocusability = "blocksDescendants"는 완벽했습니다. –

    +1

    당신, 내 친구, 내 개인 영웅입니다. 당신은 최고 득표 한 사람이어야합니다! 거의 모든 경우에 훨씬 더 좋습니다! –

    +0

    이것은 허용 된 대답이어야합니다. 그것은 나를 위해 완벽하게 작동했습니다. 목록 항목의 모든보기가 초점을 잃을 필요가있는 것처럼 보입니다.이보기는 개별적으로 설정하지 않고도 수행합니다. – rushinge

    2

    당신의 버튼