Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ListView does not render all items until interacted with

I have a very strange problem while using my ListView.

Only a part of my adapter items are renderd in the listview on screen but when I interact with the listview (ie tries to scroll it) all items are renderd properly.

This fenonemon only occurs if i have less items than the screen can show. Take a look at these screenshots below.

Before interaction: enter image description here

After interaction: enter image description here

Source code of activity where adding items:

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);

Code of adapter:

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;
    }
}

Code of layout:

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);
like image 502
Richard Avatar asked Jul 13 '12 09:07

Richard


1 Answers

try calling notifyDataSetChanged() in runOnUIThread() method like I have shown below and it will work like a charm. :)

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        messageAdapter.notifyDataSetChanged();
                    }
                });
like image 178
Abhishek Akhani Avatar answered Oct 19 '22 02:10

Abhishek Akhani