2012-07-13 8 views
12

Tengo un problema muy extraño al usar mi ListView.ListView no representa todos los elementos hasta interactuar con

Solo una parte de mis elementos de adaptador se renderizan en la vista de lista en la pantalla, pero cuando interactúo con la vista de lista (es decir, intenta desplazarla) todos los elementos se procesan correctamente.

Este fenonemon solo ocurre si tengo menos elementos de los que la pantalla puede mostrar. Eche un vistazo a estas capturas de pantalla a continuación.

Antes de interacción: enter image description here

Después de interacción: Código enter image description here

Fuente de actividad donde la adición de elementos:

String[] jRests = getResources().getStringArray(R.array.j_restaurants); 
     String[] lRests = getResources().getStringArray(R.array.l_restaurants); 

     items = new ArrayList<Object>(); 
     items.add(getString(R.string.campus_j)); 
     for(String item : jRests){ 
      String[] val = item.split(",,,"); 
      items.add(new FoodSectionListItem(new Restaurant(val[0], val[1], val[2], ""))); 
     } 
     items.add(getString(R.string.campus_l)); 
     for(String item : lRests){ 
      String[] val = item.split(",,,"); 
      items.add(new FoodSectionListItem(new Restaurant(val[0], val[1], val[2], ""))); 
     } 

     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
     adapter = new BaseSectionAdapter(this, R.layout.list_item_fragment_header); 
     if(!isTabletView()){ 
      adapter.setSelectedItem(-1); 
     } 
     adapter.setItems(items); 

Código de adaptador:

public class BaseSectionAdapter extends AmazingAdapter { 

    private LayoutInflater inflater; 
    private int selectedItem = 0; 
    private List<Object> items; 
    private List<SectionItem> sections = new ArrayList<SectionItem>(10); 
    private List<Class> itemTypes = new ArrayList<Class>(); 
    private List<Integer> sectionPositions = new ArrayList<Integer>(); 
    private int listHeaderLayoutId; 
    private View headerView; 

    public static interface ISectionListItem { 
     public void setProps(View convertView, int position, int selectedItem); 
     public View getLayout(LayoutInflater inflater); 
    } 

    private class SectionItem implements Serializable { 
     private static final long serialVersionUID = -8930010937740160935L; 
     String text; 
     int position; 

     public SectionItem(String text, int position) { 
      this.text = text; 
      this.position = position; 
     } 
    } 

    public BaseSectionAdapter(Context context, int listHeaderLayoutId) { 
     this.listHeaderLayoutId = listHeaderLayoutId; 
     init(context); 
    } 

    public BaseSectionAdapter(Context context, int listHeaderLayoutId, List<Object> listItems) { 
     this.listHeaderLayoutId = listHeaderLayoutId; 
     init(context); 
     initListItems(listItems); 
    } 

    private void init(Context context) { 
     inflater = (LayoutInflater) context 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    public void setSelectedItem(int position) { 
     selectedItem = position; 
    } 

// public List<ListItem> getItems() { 
//  return items; 
// } 

    private void initListItems(List<Object> itemList) { 
     int curSection = -1; 
     //int curPosition = 0; 
     //curSection = 0; 

     this.items = itemList; 
     itemTypes.clear(); 
     sections.clear(); 
     sectionPositions.clear(); 



     int listSize = itemList.size(); 
     for(int i = 0; i < listSize; i++){ 
      Object currentItem = items.get(i); 
      if(currentItem instanceof String){ 
       sections.add(new SectionItem((String) currentItem,i)); 
       curSection++; 
      } 
      if(!itemTypes.contains(currentItem.getClass())){ 
       itemTypes.add(currentItem.getClass()); 
      } 


      sectionPositions.add(curSection); 
     } 

     Log.d("test", "No of items = "+items.size()); 
     Log.d("test", "No of itemtypes = "+itemTypes.size()); 
     Log.d("test", "View type count = "+getViewTypeCount()); 
    } 

    public void setItems(List<Object> itemList) { 
     initListItems(itemList); 
    } 

    public int getCount() { 
     return items==null?0:items.size(); 
    } 

    @Override 
    public int getViewTypeCount(){ 
     return (itemTypes.size() == 0)?1:itemTypes.size(); 
    } 

    @Override 
    public int getItemViewType(int position){ 
     return itemTypes.indexOf(items.get(position).getClass()); 
    } 

    @Override 
    public boolean isEnabled(int position){ 
     return !(items.get(position) instanceof String || items.get(position) instanceof EmptySectionListItem); 
    } 

    @Override 
    public Object getItem(int position) { 
     return items.get(position); 
    } 

    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    protected void onNextPageRequested(int page) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    protected void bindSectionHeader(View view, int position, 
      boolean displaySectionHeader) { 
//  TextView lSectionTitle = (TextView) view 
//    .findViewById(R.id.txt_list_header); 
//  if (displaySectionHeader) { 
//   lSectionTitle.setVisibility(View.VISIBLE); 
//   lSectionTitle 
//     .setText(getSections()[getSectionForPosition(position)]); 
//  } else { 
//   lSectionTitle.setVisibility(View.GONE); 
//  } 
    } 

    @Override 
    public View getAmazingView(int position, View convertView, ViewGroup parent) { 
     Object curItemObject = items.get(position); 
     boolean isHeader = (curItemObject instanceof String); 

     if(convertView == null){ 
      if(isHeader && headerView != null){ 
       convertView = headerView; 
      }else if(isHeader){ 
       convertView = inflater.inflate(listHeaderLayoutId, null); 
       headerView = convertView; 
      }else{ 
       convertView = ((ISectionListItem) curItemObject).getLayout(inflater); 
      } 
     } 
     if(isHeader){ 
      TextView header = ((TextView)convertView.findViewById(R.id.txt_list_header)); 
      header.setText((String)curItemObject); 
     }else{ 
      ((ISectionListItem)curItemObject).setProps(convertView, position, selectedItem); 
     } 
     return convertView; 
    } 

    @Override 
    public void configurePinnedHeader(View header, int position, int alpha) { 

     TextView textView = ((TextView)header.findViewById(R.id.txt_list_header)); 
     textView.setText(getSections()[getSectionForPosition(position)]); 
    } 

    @Override 
    public int getPositionForSection(int section) { 
     if(section >= sections.size()){ 
      return 0; 
     } 

     return sections.get(section).position; 
    } 

    @Override 
    public int getSectionForPosition(int position) { 
     return sectionPositions.get(position); 
    } 

    @Override 
    public String[] getSections() { 
     String[] res = new String[sections.size()]; 
     for (int i = 0; i < res.length; i++) { 
      res[i] = sections.get(i).text; 

     } 
     return res; 
    } 
} 

Código del diseño:

LinearLayout layout = new LinearLayout(this); 
      layout.setOrientation(LinearLayout.HORIZONTAL); 

      FrameLayout listLayout = new FrameLayout(this); 
      LinearLayout.LayoutParams listParams = new LinearLayout.LayoutParams(0, FrameLayout.LayoutParams.MATCH_PARENT); 
      listParams.weight = 1; 
      listLayout.setId(LIST_FRAGMENT_VIEW_ID); 

      FrameLayout detailLayout = new FrameLayout(this); 
      LinearLayout.LayoutParams detailParams = new LinearLayout.LayoutParams(0, FrameLayout.LayoutParams.MATCH_PARENT); 
      detailParams.weight = 2; 
      detailLayout.setId(DETAIL_FRAGMENT_VIEW_ID); 

      layout.addView(listLayout, listParams); 
      layout.addView(detailLayout, detailParams); 

      if(savedInstanceState == null){ 

      FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 

      ft.add(listLayout.getId(), (Fragment) listFragment, TWO_PANEL_LIST_FRAGMENT_TAG); 
      ft.add(detailLayout.getId(), detailFragment); 
      ft.commit(); 

      } 
      setContentView(layout); 
+0

¿Se puede añadir un código de adaptador ...? – Kamal

+0

agregue el código fuente donde está agregando elementos a la fuente de datos de respaldo de su vista de lista, y la creación del adaptador –

+0

muestra también la fuente de diseño de ListView.:) –

Respuesta

1

¡Lo resolvió!

El problema fue que el adaptador intentaba reutilizar el mismo elemento de sección. ¡¡¡No está bien!!!

¡Se ha cambiado para inflar el elemento de la sección cada vez que tocamos una sección!

+1

¿me puede ayudar por favor, tengo el mismo problema, ¿puede explicar cómo lo resolvió? tengo que hacer clic en la pantalla para cargar listview –

+1

una respuesta adecuada debe explicar cómo resolver el problema, no solo insinuarlo. especialmente si responde su propia pregunta ... – ndori

0

no sé qué causa el problema, pero si no encuentra una solución lógica para que usted podría intentar algo como esto:

  • gatillo un onTouchEvent() programáticamente cada vez que inicie el ListView.
  • desplácese hacia abajo y realice una copia de seguridad mediante programación tan pronto como se inicie ListView.

etc ..

0

Añadir componente ListView a layout.xml y añada contenido de lista para eso. No use FrameLayout ya que probablemente sea la causa del problema. Está actualizando el contenido después del toque, por lo que el diseño en el que se encuentra no implementa la configuración correcta de onCreate() como lo tiene el widget ListView.

+0

¿Qué quieres decir con que no está implementando el onCreate correcto? Im creando la disposición programáticamente, a la que luego agrego mis fragmentos. Intenté cambiar los dos FrameLayout por LinearLayout, no hubo diferencia:/ – Richard

+0

@Richard ¿Dónde agrega un ListView? De acuerdo con su código, no está implementando un ListView. – CommonKnowledge

+0

'ft.add (listLayout.getId(), (Fragment) listFragment, TWO_PANEL_LIST_FRAGMENT_TAG);' im agregando un listfragment – Richard

0

¿Está llamando al método notifyDataSetChanged() en su adaptador después de agregar nuevos elementos? Esto hace que la vista de lista actualice su vista cuando se cambia el conjunto de datos subyacente.

Si aún no funciona, intente notifyDataSetInvalidated() que hace que la vista de lista se vuelva a dibujar por completo.

+0

Probé este. No tiene efecto. Comenzando a pensar que el fragmento de lista podría ser el problema aquí. Im añadiendo – Richard

5

intente llamar notifyDataSetChanged() en el método runOnUIThread() como he mostrado a continuación y funcionará como un amuleto. :)

   runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         messageAdapter.notifyDataSetChanged(); 
        } 
       }); 
+0

Aparentemente no es la solución para la pregunta original, pero esto me solucionó el mismo problema. Llamar a notifyDataSetChanged() desde otro subproceso no es confiable. – Ashley

Cuestiones relacionadas