如何更改Android中ListView中不可见项的背景颜色

时间:2015-01-22 23:52:48

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

我正在尝试制作一个导航抽屉,它根据从应用程序另一部分收到的整数改变ListView中项目的背景颜色 - 即不基于点击的项目。我已设法在导航抽屉中为两个单独的项目着色,但显然我的方式仅适用于可见的项目。我尝试了一个解决方案,包括在更改背景颜色之前滚动到所需的项目,但我无法找到一种方法来计算项目在向下滚动后的数字,因为getChildAt(position)似乎开始在第一个可见项目。

有什么办法可以解决这个问题,而无需重新整理导航抽屉吗?我搜索了一些关于如何做这样的侧边栏菜单的指南,但大多数意味着我必须在XML中设置静态项目 - 而且由于我的列表需要定期更改,我认为这将是最简单的方法,但对于所有人来说我知道这可能是一个不好的方法。

这是在onCreate上运行的代码:

mTitle = mDrawerTitle = getTitle();
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
        R.drawable.ic_drawer, R.string.navigation_drawer_open,
        R.string.navigation_drawer_close) {

    public void onDrawerClosed(View view) {
        super.onDrawerClosed(view);
        getActionBar().setTitle(mTitle);
    }

    public void onDrawerOpened(View drawerView) {
        super.onDrawerOpened(drawerView);
        getActionBar().setTitle(mDrawerTitle);
        dList = (ListView) findViewById(R.id.left_drawer);

        // My work-around to not get force close if item isn't visible
        if (itemOne > -1) {
            int visibleChildCount = (dList.getLastVisiblePosition() - dList
                    .getFirstVisiblePosition()) + 1;
            if (visibleChildCount > itemOne)
                dList.getChildAt(itemOne).setBackgroundColor(
                        Color.parseColor("#d3d3d3"));
        }
        if (itemTwo > -1) {
            int visibleChildCount = (dList.getLastVisiblePosition() - dList
                    .getFirstVisiblePosition()) + 1;
            if (visibleChildCount > itemTwo)
                dList.getChildAt(itemTwo).setBackgroundColor(
                        Color.parseColor("#33B5E5"));
        }

    }
};


    mDrawerLayout.setDrawerListener(mDrawerToggle);
    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);

其余的代码:

dLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
dList = (ListView) findViewById(R.id.left_drawer);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myArrayOfItems);
dList.setAdapter(adapter);

dList.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
        dList.setItemChecked(position, true);
        dLayout.closeDrawers();
        stateChanged = true;

            // Non-relevant action when item is clicked

    }
});

最后,活动XML:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

<RelativeLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerHorizontal="true"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">

     <!-- Items in my main activity -->

</RelativeLayout>

<ListView android:id="@+id/left_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"
    android:dividerHeight="0dp"
    android:background="#fff"/>

</android.support.v4.widget.DrawerLayout>

如果您需要任何其他信息,请与我们联系。如果我在任何其他问题中错过了答案,或者这是一个愚蠢的问题,我很抱歉。我已经尝试过一段时间了,但是由于我是初学者,我还没有完全弄清楚如何做到这一点,所以如果有人能帮我这个,我真的很感激!

修改

感谢darnmason我终于开始工作了。如果有人有兴趣,上面的代码将使用以下更改。

将行 adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,myArrayOfItems); 更改为:

adapter = new NavigationAdapter(this, android.R.layout.simple_list_item_1, myArrayOfItems);

然后使用以下内容创建类NavigationAdapter.java(并确保以某种方式从主活动可以访问整数itemOne / itemTwo):

import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;

public class NavigationAdapter extends ArrayAdapter<String> {

    // Create constructor matching super
    public NavigationAdapter(Context context, int resource, String[] objects) {
        super(context, resource, objects);
    }

    // Override method so that you can modify the view
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = super.getView(position, convertView, parent);
        // modify your view depending on position
        if (position == itemOne) {
                boolean positionOne = true;
            view.setBackgroundColor(positionOne ? Color.parseColor("#d3d3d3") : Color.WHITE);
        } else if (position == itemTwo) {
                boolean positionTwo = true;
            view.setBackgroundColor(positionTwo ? Color.parseColor("#33B5E5") : Color.WHITE);
        } else
            view.setBackgroundColor(Color.WHITE);

        return view;
    }
}

另外,请确保删除以前代码中的以下行:

        // My work-around to not get force close if item isn't visible
        if (itemOne > -1) {
            int visibleChildCount = (dList.getLastVisiblePosition() - dList
                    .getFirstVisiblePosition()) + 1;
            if (visibleChildCount > itemOne)
                dList.getChildAt(itemOne).setBackgroundColor(
                        Color.parseColor("#d3d3d3"));
        }
        if (itemTwo > -1) {
            int visibleChildCount = (dList.getLastVisiblePosition() - dList
                    .getFirstVisiblePosition()) + 1;
            if (visibleChildCount > itemTwo)
                dList.getChildAt(itemTwo).setBackgroundColor(
                        Color.parseColor("#33B5E5"));
        }

1 个答案:

答案 0 :(得分:0)

应该在适配器中处理列表中每个项目的呈现。您应该做的是扩展ArrayAdapter并覆盖getView,如下所示:

View view = super.getView(position, convertView, parent);
boolean selected = position matches any of your indexes;
view.setBackgroundColor(selected ? selectedColor : normalColor);
return view;

设置背景的另一种方法是使用具有选定状态和默认状态的可绘制状态列表。然后你只需要拨打view.setSelected(selected)

编辑:扩展ArrayAdapter

创建一个新文件,我喜欢创建一个新的包,例如在com.domain.name.adapters之下对所有自定义适配器进行分组。

// Create new class extending ArrayAdapter<String>
public class NavigationAdapter extends ArrayAdapter<String> {

    // Create constructor matching super
    public NavigationAdapter(Context context, int resource, String[] objects) {
        super(context, resource, objects);
    }

    // Override method so that you can modify the view
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = super.getView(position, convertView, parent);
        // modify your view depending on position
        return view;
    }
}

然后在代码中用NavigationAdapter代替ArrayAdapter。您可能必须公开方法以在NavigationAdapter上设置所选索引,除​​非您将它们放在某个可在地上访问的位置。