2011-02-09 8 views
2

내 Android 앱에서 탐색을 위해 ListView를 사용하여 해당 활동의 onCreate 메소드에서 BaseAdapter를 만들고 설정합니다.BaseAdapter.notifyDataSetChanged 요소의 순서를 반전합니다.

는 BaseAdapter 요소를 검색하기 위해 (cache.getNavigation을()) ArrayList에 액세스 :

public class NavigationAdapter extends BaseAdapter { 
    Context mContext; 

    public NavigationAdapter(Context c) { 
     mContext = c; 
    } 

    @Override 
    public int getCount() { 
     return cache.getNavigation() != null ? cache.getNavigation().size() 
       : 0; 
    } 

    @Override 
    public Object getItem(int position) { 
     return cache.getNavigation() != null ? cache.getNavigation().get(
       position) : 0; 
    } 

    @Override 
    public long getItemId(int position) { 
     return cache.getNavigation() != null ? cache.getNavigation().get(
       position).getId() : 0; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View v; 
     if (convertView == null) { 
      LayoutInflater li = getLayoutInflater(); 

       v = li.inflate(R.layout.list_nav_icon, null); 
       TextView tv = (TextView) v.findViewById(R.id.list_nav_text); 
       tv.setText(((TemplateInstanceDto) getItem(position)) 
         .getName()); 

       ImageView icon = (ImageView) v 
         .findViewById(R.id.list_nav_icon); 
       byte[] binary = ((TemplateInstanceDto) getItem(position)) 
         .getIcon(); 
       Bitmap bm = BitmapFactory.decodeByteArray(binary, 0, 
         binary.length); 
       icon.setImageBitmap(bm); 

       ImageView arrow = (ImageView) v 
         .findViewById(R.id.list_nav_arrow); 
       arrow.setImageResource(R.drawable.arrow); 


     } else { 
      v = convertView; 
     } 
     return v; 
    } 
} 

그래서 탐색 캐시에서 시작에 내장되어 있습니다. 한편 I는 서버에서 탐색의 ArrayList를 검색하는 AsyncTask를 시작하고 변경 할 때 캐시에 새 탐색을 저장합니다

private class RemoteTask extends 
     AsyncTask<Long, Integer, List<TemplateInstanceDto>> { 
    protected List<TemplateInstanceDto> doInBackground(Long... ids) { 
     try { 
      RemoteTemplateInstanceService service = (RemoteTemplateInstanceService) ServiceFactory 
        .getService(RemoteTemplateInstanceService.class, 
          getClassLoader()); 

      List<TemplateInstanceDto> templates = service 
        .findByAccountId(ids[0]); 

      return templates; 
     } catch (Exception e) { 
      return null; 
     } 
    } 

    protected void onPostExecute(List<TemplateInstanceDto> result) { 
     if (result != null && result.size() > 0) { 
      cache.saveNavigation(result); 
      populateData(); 
     } else { 
      Toast text = Toast.makeText(ListNavigationActivity.this, 
        "Server communication failed.", 3); 
      text.show(); 
     } 
    } 
} 

내가 populateData()에 불과, ListView에 나던 업데이 트를 할 수없는 경우. ((BaseAdapter) ListView.getAdapter()).notifyDataSetChanged()으로 전화하면보기가 업데이트되지만 순서가 반대로됩니다. 첫 번째 항목은 마지막 항목이고 마지막 항목은 첫 번째 항목입니다.

개최 필요! 미리 감사드립니다.

답변

2

문제의 getView() 함수에있다. 다른 메서드 호출을 통해 뷰 개체는 위치와 결합되지는 않지만 캐시됩니다. 목록이 반전지고있는 이유

pos1: View1 
pos2: View2 
pos3: View3 
pos3: View1 
pos2: View2 
pos1: View3 

그게 전부 : 적절한 로그를

, 당신은 또한이 동작을 볼 수 있습니다. 해결책 : 오브젝트가 존재하는 경우에도 getView를 호출 할 때마다 값을 값으로 설정하십시오. 예 :

public View getView(int position, View convertView, ViewGroup parent) { 
    View v; 
    if (convertView == null) { 
     LayoutInflater li = getLayoutInflater(); 
     v = li.inflate(R.layout.list_nav_icon, null); 
    } else { 
     v = convertView; 
    } 
    TextView tv = (TextView) v.findViewById(R.id.list_nav_text); 
    tv.setText(((TemplateInstanceDto) getItem(position)) 
        .getName()); 

    ImageView icon = (ImageView) v 
        .findViewById(R.id.list_nav_icon); 
    byte[] binary = ((TemplateInstanceDto) getItem(position)) 
        .getIcon(); 
    Bitmap bm = BitmapFactory.decodeByteArray(binary, 0, 
        binary.length); 
    icon.setImageBitmap(bm); 

    ImageView arrow = (ImageView) v 
        .findViewById(R.id.list_nav_arrow); 
    arrow.setImageResource(R.drawable.arrow); 

    return v; 
} 
+0

완벽한 답. 나는 convertView에 익숙하지 않았지만, 그 동안 나는 그것이 무엇인지를 이해했다. 고맙습니다. – Konsumierer

0

리모컨 서비스가 새 데이터를 올바르게 반환 했습니까? 나는 그 부분 주위에 디버깅을 할 것이고, 게시 된 코드는 나를 위해 괜찮아 보인다.

또한, 해결 방법이있다 : 사용자의 ListView의 StackFromBottom 속성 :

+0

원격 서비스가 올바르게 주문 된 데이터를 제공한다는 것은 확실합니다. AsyncTask를 수동으로 트리거하면 순서가 매번 바뀝니다 (맨 위, 맨 아래, 맨 아래, ...). 지금 당장, 나는'populateData()'에 매번 새로운 어댑터를 설정할 수있는 해결 방법을 발견했다 : ListView.setAdapter (new NavigationAdapter (this)) – Konsumierer

관련 문제