2012-03-14 4 views
1

(상대 레이아웃) 뷰를 보유하고있는 ViewHolder가 목록에 추가되었습니다. 각 개별 레이아웃에는 삭제 버튼이 있습니다. 삭제 버튼을 클릭하고 화면을 업데이트 할 수 있기를 원합니다. 현재 구현은 작동하지만 뒤로 버튼을 누른 다음 화면으로 돌아가 삭제 된 것을 확인해야합니다.ViewHolder (목록)에서 항목 삭제, 화면 업데이트

본질적으로이 항목은 동적으로 항목이 추가되는 장바구니입니다. 즉, 삭제 버튼을 클릭 할 때 화면을 업데이트 할 onClick 이벤트에 무엇을 추가해야합니까? Invalidate()가 작동하지 않습니다.

알림 : 이러한 메서드는 onCreate()와 분리되어 있으므로 finish() 또는 getIntent() 또는 그와 같은 메서드를 사용할 수 없습니다.

편집 : 나는 사용자 지정 ListAdapter와의 ListView를 사용하는 가정 라이 니어의 대답

+0

notifydatasetchanged()를 사용해 보셨나요? – dymmeh

+0

listadapter를 사용하여 listview를 사용하고 어댑터 (직접 메소드가 ArrayAdapter에 존재 함)를 조작하고 어댑터에서 notifyDatasetChanged를 사용하여 뷰를 새로 고침해야합니다. – njzk2

답변

3

에 추가 의견을 추가 한? 데이터 집합 (예 : ArrayList)을 생성자의 ListAdapter에 전달합니다. 그런 다음 데이터 세트를 조작하면 (예 : dataset.remove(Object object)) ListAdapter에서 .notifyDatasetChanged()으로 전화하십시오. 그러면 어댑터가 속한보기를 갱신합니다.

업데이트

'까지 그 나사 홀더의 위치'에 의해 당신이 무엇을 의미하는지 정말 모르겠어요

. ViewHolder는 기본적으로 getView() -method에서 조작하려는 View에 대한 참조를 보유하기위한 것입니다. 데이터 세트는 ViewHolder에서 분리되어 있으므로 데이터 세트에서 항목을 제거해도 레이아웃에 영향을 미치지 않아야합니다. 목록보기에서 항목을 삭제하는 경우는 제외합니다.

다음은 작동해야하는 예입니다. 나는 가능한 한 많이 설명하려고 노력했다. 대부분을 알고 있을지 모르지만 나중에 참조 할 때/Google 직원을 위해 몇 가지 추가 정보를 제공합니다.

참고 : 완벽하지는 않지만 잘 처리되어야합니다.

MyAdapter myAdapter = new MyAdapter(this, R.layout.listitem, cartItems); 
ListView listview = (ListView) findViewById(R.id.listview); 
listview.setAdapter(myAdapter); 

cartItems.remove(object); 
myAdapter.notifyDatasetChanged(); 

이리스트 뷰에서 항목을 제거하고 예,이 위치의 인덱스를 재설정합니다 :

public class MyAdapter extends ArrayAdapter<CartItem> { 

// This is our data-model. 
// let's say your cartitems only contain an id and name 
// normally this would be defined elsewhere in your code 
public class CartItem { 
    public int id; 
    public String product_name; 
} 

/* 
* ViewHolders are basically meant to keep a reference to the Views, 
* so that you don't have to use .findViewById() on every getView() 
* for the elements you're trying to manipulate. 
* 
* .findViewById() finds Views by traversing the hierarchy (heavy). 
* This generally isn't a problem, but we want to avoid this in 
* ListViews because getView() gets called a lot - which makes our app slow. 
* 
* We will want to keep a reference to our TextView and Button, 
* because these are the elements we want to change every getView(). 
* Not to the RelativeLayout, because it's already passed in convertView 
* (after you inflated it for the first time) and we're not manipulating it 
* anyway. 
*/ 
public class ViewHolder { 

    public Button deleteButton; 
    public TextView mTextView; 

} 

public MyAdapter(Context context, int textViewResourceId, 
     ArrayList<CartItem> cartItems) { 

    // here, we tie our data (ArrayList of CartItem's) 
    // to the ListAdapter (ArrayAdapter = extended ListAdapter) 
    super(context, textViewResourceId, cartItems); 
} 


    // this method 
public View getView(final int position, View convertView, ViewGroup parent) { 

    final ViewHolder holder; 

    // if convertView == null, that means we haven't inflated our listitem yet. 
    if(convertView == null) { 

     // so, we'll inflate our listitem now. 
     // after this, convertView will contain our RelativeLayout 
     // and its children/subviews 
     LayoutInflater inflater = (LayoutInflater) getContext() 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     convertView = inflater.inflate(R.layout.listitem, null); 

     // now we're gonna instantiate the ViewHolder to keep a reference 
     // to our TextView and ImageView 
     holder = new ViewHolder(); 

     holder.mTextView = (TextView) convertView 
       .findViewById(R.id.listitem_textview); 
     holder.deleteButton = (Button) convertView 
       .findViewById(R.id.listitem_deletebutton); 

     // Now that we have our reference, we want to make sure we can 
     // keep our reference by using tags. Tags are a way to attach 
     // data to a View. 
     convertView.setTag(holder); 
    } else { 
     // if we have already inflated our listitem, we just get the 
     // references to our Views from the tag 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    // we want to read/do-stuff-with a specific CartItem. First, get 
    // a reference to the data-object. 
    final CartItem mCartItem = (CartItem) getItem(position); 

    // now, it's time to manipulate our views 
    holder.mTextView.setText(mCartItem.product_name); 
    holder.deleteButton.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 

      // then, pass a signal to MyAdapter that we want to remove 
      // this item from our dataset 
      remove(mCartItem); 
      // now, we want to update any (list)views attached to our MyAdapter 
      // this will let the ListView update itself 
      notifyDataSetChanged(); 
     } 

    }); 

    // convertView will be recycled, which means what we output here 
    // will be the input for the next getView()-call 
    return convertView; 
} 
} 

당신이 당신의 활동에서 데이터 집합을 조작하려면

는 다음을 수행합니다. 그러나 ListAdapter 권한을 설정하면 문제가되지 않습니다.

+0

이렇게하면 해당 뷰 중 하나에서 작동합니다. 삭제합니다. 그런 다음 다른 단추를 클릭하면 내 ArrayList의 범위를 벗어난 인덱스로 충돌합니다. 따라서 디버깅 할 때 목록에 두 개의 항목을 추가했습니다. 그런 다음 첫 번째 항목을 삭제하므로 두 번째 항목이 목록에서 첫 번째 위치로 이동했습니다. 그런 다음 남은 항목 만 삭제하려고하면 충돌이 발생합니다. 여기 내 onClick에있는 코드가 삭제 단추입니다. (I는 (변경된 시도) 및 무효화()) 'holder.buttonLine.setOnClickListener (새 View.OnClickListener() \t \t \t \t {\t \t 공공 무효 온 클릭 (보기 V) { cartItems.remove (위치) ; notifyDataSetChanged();}}); ' – Kcvin

+0

추가 디버깅을 통해. dataSet.remove()를 찾았습니다. ArrayList에서 제거하고 모든 요소를 ​​빈 공간을 채우기 위해 이동합니다.음, 홀더에 설정된 위치에서 나사를 조이십시오. 따라서 설정된 이전 위치를 삭제하려고합니다. 어쨌든 이것을 막기 위해서? – Kcvin

+0

답변을 예제로 업데이트했습니다. 내가 겪고있는 문제가 무엇인지 잘 모르겠지만, 데이터 세트와 ViewHolder를 혼합하는 것과 관련이 있다고 생각합니다. 나는 그것이 유용하길 바래! – Reinier