2015-01-28 1 views
0

나는 현재 내 item_exercise.xml에 조건부로 표시하는 buttons_row 있습니다Android에서 재생 된보기를 사용하지 않도록 ListView에서 항목을 가져 오는 방법은 무엇입니까?

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:id="@+id/item_exercise" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:minHeight="?android:attr/listPreferredItemHeight" 
       > 

    <RelativeLayout 
     android:id="@+id/text_row" 
     android:layout_width="match_parent" 
     android:layout_height="60dp"> 

     <TextView 
      android:id="@+id/exercise_name_value" 
      style="@style/h5" 
      android:text="@string/no_exercise" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_marginStart="24dp" 
      android:gravity="center_vertical" 
      android:layout_centerVertical="true" 
      android:layout_toStartOf="@+id/item_nav_image" 
      /> 

     <ImageView 
      android:id="@+id/item_nav_image" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignParentEnd="true" 
      android:layout_marginEnd="12dp" 
      android:src="@drawable/ic_action_expand" 
      android:contentDescription="@string/nav_expand_collapse" 
      android:layout_centerVertical="true" 
      /> 
    </RelativeLayout> 

    <RelativeLayout 
     android:id="@+id/buttons_row" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@id/text_row" 
     android:visibility="gone" 
     > 

     <ImageButton 
      android:id="@+id/exercise_rename_btn" 
      android:layout_width="120dp" 
      android:layout_height="wrap_content" 
      android:src="@drawable/ic_action_mic" 
      android:contentDescription="@string/rename" 
      android:layout_marginStart="10dp" 
      /> 

     <ImageButton 
      android:id="@+id/exercise_delete_btn" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:src="@drawable/ic_action_discard" 
      android:contentDescription="@string/delete" 
      android:layout_alignParentEnd="true" 
      /> 
    </RelativeLayout> 

</RelativeLayout> 

내가 ViewHolder 패턴을 사용하고 내가 문제로 실행하면 내 목록에서 운동을 삭제할 때를 때문에 buttons_row와 재활용 뷰 (표시됨)은 다른 item_exercise 항목으로 재활용됩니다. 이 문제를 어떻게 해결할 수 있을지 궁금합니다.

Adapter.java : 내 displayNavCorrectly() 메소드는 일을 해결하기 위해 줄 알았는데하지만하지 않았다

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    final ViewHolder holder; 
    if (convertView == null) { 
     convertView = View.inflate(mContext, R.layout.item_exercise, null); 
     holder = new ViewHolder(); 
     holder.rithmId = 0; 
     holder.exerciseName = (TextView) convertView.findViewById(R.id.exercise_name_value); 
     holder.renameButton = (ImageButton) convertView.findViewById(R.id.exercise_rename_btn); 
     holder.deleteButton = (ImageButton) convertView.findViewById(R.id.exercise_delete_btn); 
     holder.buttonsRow = (RelativeLayout) convertView.findViewById(R.id.buttons_row); 
     holder.navImage = (ImageView) convertView.findViewById(R.id.item_nav_image); 
     holder.navShown = EXPAND; 
     convertView.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    final BaseAdapter baseAdapter = this; 
    final ActiveRithm rithm = (ActiveRithm) getItem(position); 
    holder.rithmId = rithm.getRithmID(); 
    holder.exerciseName.setText(rithm.getName()); 
    holder.displayNavCorrectly(); 

    convertView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      holder.toggleNav(); 
     } 
    }); 

    holder.deleteButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      //brings up confirmation dialog to delete this exercise/rithm 
     } 
    }); 
    return convertView; 
} 



static class ViewHolder { 
    public int rithmId; 
    public TextView exerciseName; 
    public ImageButton renameButton; 
    public ImageButton deleteButton; 
    public String navShown; 
    public RelativeLayout buttonsRow; 
    public ImageView navImage; 

    public void toggleNav() { 
     Log.d(TAG, "navShown: " + navShown); 
     if (navShown != null && navShown.equals(EXPAND)) { 
      // display buttons 
      buttonsRow.setVisibility(View.VISIBLE); 
      // change image to be collapse 
      navImage.setImageResource(R.drawable.ic_action_collapse); 
      navShown = COLLAPSE; 
     } else { 
      // hide buttons 
      buttonsRow.setVisibility(View.GONE); 
      // change the image to be expand 
      navImage.setImageResource(R.drawable.ic_action_expand); 
      navShown = EXPAND; 
     } 
    } 

    /** 
    * Sometimes when you delete a rithm, the holder does not display the correct navigation 
    * This method makes sure that recycled views are being displayed correctly. 
    */ 
    public void displayNavCorrectly() { 
     Log.d(TAG, "displayNavCorrectly: " + navShown); 

     if (navShown != null && navShown.equals(EXPAND)) { 
      // Hide buttons and image should be expand 
      buttonsRow.setVisibility(View.GONE); 
      navImage.setImageResource(R.drawable.ic_action_expand); 
     } else { 
      buttonsRow.setVisibility(View.VISIBLE); 
      navImage.setImageResource(R.drawable.ic_action_collapse); 
     } 
    } 
} 

. 내 객체 안에 UI의 '상태'를 저장해야합니까? 아니면 이것을하는 더 좋은 방법이 있습니까?

답변

1

가장 간단한 방법은 매번보기를 재활용하고 매번 새로운보기를 부 풀리는 것입니다. 그러나 그것은 성능에 좋지 않을 것입니다.

전체적으로 홀더 패턴은 뷰가 동일 할 때 findViewById를 호출하여 뷰를 찾는 것을 피하기 위해 사용됩니다. 그래서 rithmId와 navShown을 가지고 있지 않아야합니다.

그런 다음보기의 상태를 설정해야합니다. buttonrows visiblity가 변경 될 수있는 경우 모든보기에 대해 설정하십시오. 귀하의 경우에는 단추를 숨기거나 표시하려는 것 같습니다. 따라서 귀하의 데이터 (귀하의 경우 ActiveRithm)는 귀하의 소지자가 아니라 그것을 기억해야합니다.

그래서 당신이 얻을 때 개체에 현재보기

final ActiveRithm rithm = (ActiveRithm) getItem(position); 
if (rithm.showingButtons) { 
    holder.buttonsRow.setVisibility(View.VISIBLE); 
} else { 
    holder.buttonsRow.setVisibility(View.GONE); 
} 

그리고의 현재 상태를 설정하는 데 사용하여 홀더를 ​​조작하지만, 홀더 뷰와 데이터의 상태를 조작하지 않습니다 클릭합니다.

convertView.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
      rithm.showingButtons = !rithm.showingButtons; 
      if (rithm.showingButtons) { 
       holder.buttonsRow.setVisibility(View.VISIBLE); 
      } else { 
       holder.buttonsRow.setVisibility(View.GONE); 
      } 
    } 
}); 
+0

감사합니다. UI 작업을 위해 POJO를 수정해야한다는 것이 더러운 것 같아요. 더 좋은 패턴이 있나요? – Kamilski81

+1

어댑터에서 선택한 색인을 기억하게 할 수 있습니다. 목록 selectedRows = new ArrayList (); 을 선택하고 getView가 선택되었는지 확인하십시오. – mlaHackingIsMagic

관련 문제