2012-11-29 2 views
2

각 항목에 bg 이미지, textView 및 2 개의 imageView가있는 사용자 정의 LinearLayout이있는 ListView가 있습니다. LiearLayout의 BG 이미지가 텍스트 색상을 변경해야 다른 ListItem은 bg 색상, 눌렀을 때 텍스트 및 이미지 색상을 변경해야합니다.

  • 텍스트 뷰로 교체해야합니다

    • : 는 지금은 사용자가 항목을 터치하는 동안, 그 모두가 "를 누르면"상태로 전환하는 것이 필요 항목의
    • 모두 ImageViews는

    일반적으로 같은 물건을 내 선택이있는 XML 리소스를 사용하여 수행 할 것, 예를 들어 다른 이미지

  • 로 전환한다 LinearLayout은 백그라운드 용 셀렉터가있는 드로어 블을 사용하고, TextView는 셀렉터와 색상이있는 drawable을 사용하고, ImageViews는 src 용 이미지가있는 selector를 사용합니다.

    문제는 눌려진 상태가 자식 뷰 (?)가 아닌 LinearLayout에 의해 감지되므로 배경 이미지 만 변경된다는 것입니다.

    OnTouchListener를 사용하여 구현하려고했지만 목록 항목 내부의보기에 안전하게 액세스 할 수 없다는 문제가 발생합니다.

    목록 항목의 getView()에서 반환 한보기를 캐싱하여 나중에 이미지와 텍스트 색상을 변경하려고했습니다. 일반적으로 작동하지만 예 : 목록 항목 중 하나에서 다른 활동이 열리면보기가 사라지고 강조 표시된 상태가 무기한 유지됩니다. 디버깅을 시도했는데 디버거를 단계별로 실행하면 올바르게 작동합니다.

    또한 cachedView를 재사용하면 아무런 문제가없는 것처럼 보이므로 매번 목록 항목에 새로운보기가 추가됩니다 (비효율적이어야 함).

    <?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:orientation="horizontal" 
        android:background="@color/white" 
        android:gravity="center_vertical" 
        android:padding="5dp" > 
    
        <ImageView 
         android:id="@+id/img_menu_item_icon" 
         android:layout_width="48dp" 
         android:layout_height="48dp" 
         android:src="@drawable/info" /> 
    
        <TextView 
         android:id="@+id/txt_menu_item_text" 
         android:layout_width="0dp" 
         android:layout_height="wrap_content" 
         android:layout_weight="1" 
         android:textSize="24dp" 
         android:text="Menu item" 
         android:textColor="@color/text_dark" 
         android:layout_marginLeft="5dp" /> 
    
        <ImageView 
         android:id="@+id/img_menu_item_arrow" 
         android:layout_width="48dp" 
         android:layout_height="48dp" 
         android:src="@drawable/arrow" /> 
    
    </LinearLayout> 
    

    답변

    3

    많은 실험을 마침내 다음과 같이 작업했습니다. 목록 항목 레이아웃 내의 모든 하위보기는 android:duplicateParentState="true"이어야합니다. 그러면 모두 선택기 드로어 블을 사용할 수 있습니다. 코드 내부의 추가 작업은 필요하지 않습니다.

    <?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:orientation="horizontal" 
        android:background="@drawable/my_item_bg" 
        android:gravity="center_vertical" 
        android:padding="5dp" > 
    
        <ImageView 
         android:id="@+id/img_menu_item_icon" 
         android:layout_width="48dp" 
         android:layout_height="48dp" 
         android:src="@drawable/selector_info" 
         android:duplicateParentState="true" /> 
    
        <TextView 
         android:id="@+id/txt_menu_item_text" 
         android:layout_width="0dp" 
         android:layout_height="wrap_content" 
         android:layout_weight="1" 
         android:textSize="24dp" 
         android:text="Menu item" 
         android:textColor="@drawable/selector_color_my_button_text" 
         android:layout_marginLeft="5dp" 
         android:duplicateParentState="true" /> 
    
        <ImageView 
         android:layout_width="48dp" 
         android:layout_height="48dp" 
         android:src="@drawable/selector_arrow" 
         android:duplicateParentState="true" /> 
    
    </LinearLayout> 
    
    +0

    Texture의 배경을 컬러에서 drawable으로 변경 한 것을 보았습니다 ... 그렇다면 selector_color_my_button_text의 내용은 무엇입니까? –

    -1
    : 여기
    public class MyListItem extends AbstractListItem 
    { 
        private int iconResource, iconHighlightedResource; 
        private int textResource; 
        private View.OnClickListener onClickListener; 
        private LinearLayout currentView; 
    
        private ImageView imgIcon; 
        private TextView txtText; 
        private ImageView imgArrow; 
        private boolean bIsHighlighted; 
    
        public MyListItem(int iconResource, int iconHighlightedResource, int textResource, View.OnClickListener onClickListener) 
        { 
         this.iconResource = iconResource; 
         this.iconHighlightedResource = iconHighlightedResource; 
         this.textResource = textResource; 
         this.onClickListener = onClickListener; 
        } 
    
        public View getView(View cachedView) 
        { 
         this.currentView = buildView(); 
         populateView(); 
         update(); 
         return this.currentView; 
        } 
    
        private LinearLayout buildView() 
        { 
         LayoutInflater inflater = (LayoutInflater)App.get().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
         return (LinearLayout)inflater.inflate(R.layout.my_menu_item, null); 
        } 
        private void populateView() 
        { 
         this.imgIcon = (ImageView)this.currentView.findViewById(R.id.img_menu_item_icon); 
         this.txtText = (TextView)this.currentView.findViewById(R.id.txt_menu_item_text); 
         this.txtText.setText(this.textResource); 
         this.txtText.setTypeface(App.fontCommon); 
         this.imgArrow = (ImageView)this.currentView.findViewById(R.id.img_menu_item_arrow); 
         this.currentView.setOnClickListener(this.onClickListener); 
         this.currentView.setOnTouchListener(this.highlighter); 
        } 
    
        private View.OnTouchListener highlighter = new View.OnTouchListener() 
        { 
         @Override 
         public boolean onTouch(View v, MotionEvent event) 
         { 
          int nAction = event.getAction(); 
          int nActionCode = nAction & MotionEvent.ACTION_MASK; 
          switch (nActionCode) 
          { 
           case MotionEvent.ACTION_DOWN: 
            bIsHighlighted = true; 
            update(); 
            break; 
           case MotionEvent.ACTION_UP: 
           case MotionEvent.ACTION_CANCEL: 
            bIsHighlighted = false; 
            update(); 
            break; 
          } 
          return false; 
         } 
        }; 
    
        private void update() 
        { 
         if (this.bIsHighlighted) 
         { 
          updateForHighlightedState(); 
         } 
         else 
         { 
          updateForNormalState(); 
         } 
        } 
    
        private void updateForHighlightedState() 
        { 
         Resources r = App.get().getResources(); 
         this.currentView.setBackgroundResource(R.drawable.button_beveled_m_call_to_action_taking_input); 
         this.imgIcon.setImageResource(this.iconHighlightedResource); 
         this.txtText.setTextColor(r.getColor(R.color.white)); 
         this.imgArrow.setImageResource(R.drawable.arrow_highlighted); 
        } 
        private void updateForNormalState() 
        { 
         Resources r = App.get().getResources(); 
         this.currentView.setBackgroundColor(r.getColor(R.color.white)); 
         this.imgIcon.setImageResource(this.iconResource); 
         this.txtText.setTextColor(r.getColor(R.color.text_dark)); 
         this.imgArrow.setImageResource(R.drawable.arrow); 
        } 
    } 
    

    레이아웃 파일 (XML)입니다 :

    그냥 경우에, 저는 여기에 사용자 지정 목록 어댑터 사용하고 사용자 지정 목록 항목 항목의 코드

    사용자 지정 드로어 블 선택기를 만들어 listview 요소의 배경으로 설정해야합니다.

    1 단계 : 사용자가 제공 한 레이아웃 파일과 같은 적절한 배경색을 가진 다른 레이아웃 (이 예제에서는 layout_selected이지만 다른 색상으로 설정된 선형의 background 속성 포함)을 만듭니다. .

    그러면 드로어 블 폴더에 배치 될 드로어 블 셀렉터를 정의하여 어떤 배경을 어떤 인스턴스에서 사용해야하는지 정의합니다. 이것은 다음과 같이 보일 것입니다 : 당신이 당신의 어댑터에 대한 레이아웃을 설정할 때

    마지막으로
    <!-- pressed --> 
    <item android:drawable="@drawable/layout_selected" android:state_pressed="true"/> 
    <!-- focused --> 
    <item android:drawable="@drawable/layout_normal" android:state_focused="true"/> 
    <!-- default --> 
    <item android:drawable="@drawable/layout_normal"/> 
    

    대신 표준 레이아웃, 우리가 방금 만든 선택으로 설정, 목록에서 이것을 사용할 수 있습니다.

    좀 설명하기가 어려울 지 모르지만 원하는 것을 달성하기 위해 '드로어 블 셀렉터'를 사용하고 싶습니다.

    +0

    감사합니다.하지만 배경 화면에서만 작동하며 목록보기에 첨부 된보기는 변경되지 않습니다. 아니면 내가 너를 잘못 이해 했니? – iseeall

    +0

    다른 레이아웃에서 원하는 모든보기를 지정할 수 있습니다. 대체 레이아웃을 제공하여 원하는 것을 제어 할 수 있습니다. 대체 레이아웃에 적절한 값을 제공하여 UI의 모든 요소를 ​​제어 할 수 있기 때문에 사실 나를 잘못 이해했습니다. 나는 이것이 당신의 대답이라고 확신합니다. – Booger

    -1

    나는 listview에 ViewHolder 패턴을 추가하는 것이 좋습니다. 이렇게하면 목록 뷰 도면 &이 UI를 최적화합니다.

    또한 setTag를 사용하여 행의 인스턴스를 저장할 수 있습니다. 그 점에서 터치 이벤트를 처리 할 수 ​​있습니다.

    +0

    ViewHolder를 사용하는 것이 좋겠지 만 그가 묻는 문제는 해결되지 않습니다. – Booger

    +0

    실제로 시도했지만 문제는 여전히 동일합니다. View 객체 또는 ViewHolder 객체를 저장할 수 없으므로 OnTouchListener가 목록 항목 내부의 TextView에 액세스 할 수 없습니다. 대신 getView() 메소드 내부에서 수신 할 수 있습니다. – iseeall

    +0

    ok 그런 다음 각 UI 행에서 인터페이스를 구현해야하는 인터페이스 하나를 생성하여 옵저버 디자인 패턴을 사용하십시오. & ListView의 OnTouchListener에서 해당 메서드를 호출합니다. –

    관련 문제