Random behavior with Android BaseAdapter for NavigationDrawer

时间:2015-09-01 22:21:34

标签: android listview android-listview navigation-drawer baseadapter

I've implemented a NavigationDrawer. It uses a NavigationDrawerListAdapter which extends from BaseAdapter. I have 10 list items in the NavigationDrawer. I would like to set 3 of the items with a green font, the rest black font. It "disables" the list items inside configureEnabledDisabledNavDrawItems(). Then, in renderNavDrawerItemByPos() of NavDrawerListAdapter, it sets the font color to green if the list item is "disabled".

However, my problem is that each list item in the Navigation Drawer seems to be drawn randomly. For example, as I am sliding the navigation drawer up and down, random list items get colored green. I have absolutely no idea why. Any ideas?

NavigationDrawerActivity

public class NavigationDrawerActivity extends ActionBarActivity {
    public DrawerLayout mDrawerLayout;
    public ListView mDrawerList;
    public TypedArray navMenuIcons; // menu item icons
    public String[] navMenuTitles; // menu item titles
    public ArrayList<NavDrawerItem> navDrawerItems; // each drawer item
    public NavDrawerListAdapter adapter; // nav drawer adapter

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.list_slidermenu);
        navDrawerItems = new ArrayList<NavDrawerItem>();
        addNavDrawerItems(); 
        adapter = new NavDrawerListAdapter(this.getApplicationContext(), navDrawerItems);
        mDrawerList.setAdapter(adapter);

        configureEnabledDisabledNavDrawItems()
    }

    private void configureEnabledDisabledNavDrawItems() {
        for(int i=1; i < navDrawerItems.size(); i++){
            adapter.setNavigationDrawerItem(i, true);
        }

        adapter.setNavigationDrawerItem(2, false); 
        adapter.setNavigationDrawerItem(3, false); 
        adapter.setNavigationDrawerItem(6, false);
    }
}

NavigationDrawerListAdapter

public class NavDrawerListAdapter extends BaseAdapter {
    private ArrayList<NavDrawerItem> navDrawerItems;
    private List<Boolean> enabledDrawerItems;
    private LayoutInflater mInflater;

    public NavDrawerListAdapter(Context context,
            ArrayList<NavDrawerItem> navDrawerItems)    {
        super();
        this.context = context;
        this.navDrawerItems = navDrawerItems;
        this.mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        this.headerView = null;

        // Toggle enabled/disabled navigation drawer items
        enabledDrawerItems = new ArrayList<Boolean>(Arrays.asList(new Boolean[navDrawerItems.size()]));
        Collections.fill(enabledDrawerItems, new Boolean(true));
    }

    @Override
    public int getCount() {
        return navDrawerItems.size();
    }

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent)   {
        if(position == 0) {
            if(convertView == null){
                convertView = mInflater.inflate(R.layout.header_view, null);
                headerView = convertView;
            }
            return convertView;
        }

        if(convertView == null) { // Use the drawer list item view
            convertView = mInflater.inflate(R.layout.drawer_list_item, null);
        }

        renderNavDrawerItemByPos(position, convertView);

        return convertView;
    }

    private void renderNavDrawerItemByPos(int position, View convertView)   {
        TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
        txtTitle.setText("test");

        if(enabledDrawerItems.get(position) == false) {
            txtTitle.setTextColor(ColorStateList.valueOf(Color.GREEN));
            convertView.setEnabled(enabledDrawerItems.get(position));
        }
    }

    @Override
    public boolean areAllItemsEnabled()     {
        return false;
    }

    @Override
    public boolean isEnabled(int position)  {
        return enabledDrawerItems.get(position);
    }

    public void setNavigationDrawerItem(int pos, boolean enabled)   {
        enabledDrawerItems.set(pos, enabled);
    }

    @Override
    public int getItemViewType (int position) {
        if(position == 0)
            return 0;
        else
            return 1;
    }

    @Override
    public int getViewTypeCount () {
        return 2;
    }
}

1 个答案:

答案 0 :(得分:2)

If getView() is passed a recycled convertView that had previously had its title colored green, it will continue to be green, even if the current position is enabled. This is because renderNavDrawerItemByPos() only sets the color for disabled positions.

In general, whenever you get handed a recycled View, you need to make sure its entire state is set correctly for the new position.

If the default title color is black, something like this might work:

private void renderNavDrawerItemByPos(int position, View convertView)   {
    TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
    txtTitle.setText("test");

    boolean enabled = enabledDrawerItems.get(position);
    txtTitle.setTextColor(ColorStateList.valueOf(
      enabled ? Color.BLACK : Color.GREEN));
    convertView.setEnabled(enabled);
}