Добавить иконки в Android-навигатор?

Я просмотрел веб-сайт для ответа на этот вопрос, но не могу найти его, даже в официальной документации по Android.

Я занимаюсь созданием приложения, которое реализует макет навигационного ящика Android. Документацию этого макета можно найти здесь здесь и здесь.

В проектной документации, а также в ряде популярных приложений, таких как Facebook и Google Currents, элементы ящика перед ними имеют значки.

В самой проектной документации упоминается их в разделе "Содержимое ящика навигации"

Навигационные цели могут иметь необязательные ведущие значки, а также трейлинг-счетчики. Используйте счетчики, чтобы информировать пользователей о измененном состоянии данных в соответствующем представлении.

К сожалению, в документации разработчика не упоминается, как реализовать иконки в этой настройке. В нем описывается, как реализовать список элементов следующим образом:

public class MainActivity extends Activity {
private String[] mPlanetTitles;
private ListView mDrawerList;
...

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mPlanetTitles = getResources().getStringArray(R.array.planets_array);
    mDrawerList = (ListView) findViewById(R.id.left_drawer);

    // Set the adapter for the list view
    mDrawerList.setAdapter(new ArrayAdapter<String>(this,
            R.layout.drawer_list_item, mPlanetTitles));
    // Set the list click listener
    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

    ...
}
}

Поскольку их реализация использует getStringArray(), я не могу представить, как изменить элемент xml строки, чтобы включить значок.

Это непонятно, потому что многие приложения, похоже, реализуют значки до того, как каждый текстовый элемент будет отлично, а документация по дизайну даже делает ссылку на добавление значков. Я чувствую, что для добавления этих значков должен быть какой-то простой вызов API, и тем не менее единственная реализация, которую я нашел до сих пор, кажется смехотворно сложной.

Кто-нибудь знает, как добавить значки в элементы навигационного ящика? Есть ли способ сделать это с помощью простого вызова API или чтобы все эти компании (Facebook, Google и т.д.) Должны были найти способы взломать проблему?

Спасибо всем.

Ответы

Ответ 1

Поскольку их реализация использует getStringArray(), я не могу представить, как изменить элемент xml строки, чтобы включить значок.

Выбор данных модели для ListAdapter не имеет никакого влияния на то, имеют ли строки, созданные этим ListAdapter значки.

Кто-нибудь знает, как добавить значки в элементы навигационного ящика?

Поместите ImageView в макет строки для ListAdapter. Заполните это ImageView с помощью ListAdapter, например, переопределив getView() на ArrayAdapter. IOW, вы делаете это так же, как и для других ListView, как это было сделано в течение многих лет.

Есть ли способ сделать это с помощью простого вызова API

Это зависит от ваших определений "простого" и "вызова API".

Ответ 2

Создайте класс адаптера, например..

public class AdapterClass  extends ArrayAdapter<String> {
Context context;
private ArrayList<String> TextValue = new ArrayList<String>();

public AdapterClass(Context context, ArrayList<String> TextValue) {
    super(context, R.layout.row_of_drawer, TextValue);
    this.context = context;
    this.TextValue= TextValue;

}


@Override
public View getView(int position, View coverView, ViewGroup parent) {
    // TODO Auto-generated method stub

    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.row_of_drawer,
            parent, false);

    TextView text1 = (TextView)rowView.findViewById(R.id.text1);
    text1.setText(TextValue.get(position));

    return rowView;

}

}

И создайте изменение MainActivity.

использовать

   AdapterClass adClass = new AdapterClass(MainActivity.this, name_of_arrayList);

    mDrawerList.setAdapter(adClass);

insted

 mDrawerList.setAdapter(new ArrayAdapter<String>(this,
        R.layout.drawer_list_item, mPlanetTitles));

Ответ 3

Строковый массив не является определяющим макетом строк. Ваш R.layout.drawer_list_item представляет макет каждой строки списка. Если вы хотите включить изображение (или даже другой сложный макет строки), вы включите представление изображения в этот настраиваемый макет xml, заменив R.layout.drawer_list_item xml.

Что касается того, как установить изображение или текст в каждую другую строку, все это делается в методе getView() адаптера массива. Примерный пример (если в строке есть текстовое представление и изображение):

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    convertView = inflater.inflate(R.layout.revise_listview, parent,false);

    TextView tv = (TextView)convertView.findViewById(R.id.text);
    ImageView iv = (ImageView)convertView.findViewById(R.id.image);

    tv1.setText(stringArray.get(i));
    if(//condition) {
        iv.setImageResource(R.drawable.imagexx);
    }
    return convertView;
}

Более эффективный способ реализации представлений для каждой строки - использовать шаблон зрителя. Одним из многих мест, где вы можете найти примеры, является здесь.

Ответ 4

Чтобы четко структурировать это, я сделал несколько дополнительных строк кода для объектно-ориентированной реализации, которая генерирует все из массива NavigationItem - простого Java-класса, который содержит поля для текста, значка и фрагмента элемента меню:

В MainActivity моя навигация просто определяется массивом:

NavigationAdapter navigationMenuAdapter;
NavigationItem[] navigationMenuItems = {
    new NavigationItem(R.string.menu_home, R.drawable.ic_menu_home, new MainFragment()),
    new NavigationItem(R.string.menu_statistics, R.drawable.ic_statistics, new StatisticsFragment()),
    new NavigationItem(R.string.menu_settings, R.drawable.ic_settings, new SettingsFragment()),
};

protected void onCreate(Bundle savedInstanceState) {
    ...
    navigationMenuAdapter = new NavigationAdapter(this, navigationMenuItems);
    mDrawerList.setAdapter(navigationMenuAdapter);
}

...
private void selectItem(int position) {
    // Insert the fragment by replacing any existing fragment
    FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.beginTransaction()
                   .replace(R.id.content_frame, navigationMenuItems[position].fragment)
                   .commit();

    mDrawerList.setItemChecked(position, true);
    setTitle(navigationMenuItems[position].stringTitle);
    mDrawerLayout.closeDrawer(mDrawerList);
}

Класс NavigationItem:

public class NavigationItem
{
    /**
     * 
     * @param stringTitle The id of the string resource of the text of the item.
     * @param drawableIcon The id of the drawable resource of icon of the item.
     * @param fragment The Fragment to be loaded upon selecting the item.
     */
    public NavigationItem(int stringTitle, int drawableIcon, Fragment fragment)
    {
        this.stringTitle = stringTitle;
        this.drawableIcon = drawableIcon;
        this.fragment = fragment;
    }

    /**
     * The id of the string resource of the text of the item.
     */
    public int stringTitle;

    /**
     * The id of the drawable resource of icon of the item.
     */
    public int drawableIcon;

    /**
     * The Fragment to be loaded upon selecting the item.
     */
    public Fragment fragment;
}

И NavigationAdapter:

public class NavigationAdapter extends BaseAdapter {
    private Context context;
    private NavigationItem[] navigationItems;

    public NavigationAdapter(Context context, NavigationItem[] items) {
        this.context = context;
        navigationItems = items;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = null;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.list_item_navigation, parent, false);
        } else {
            row = convertView;
        }

        TextView tvTitle = (TextView) row.findViewById(R.id.textView);
        ImageView ivIcon = (ImageView) row.findViewById(R.id.imageView);

        tvTitle.setText(navigationItems[position].stringTitle);
        ivIcon.setImageResource(navigationItems[position].drawableIcon);
        return row;
    }
}

который использует очень простой xml-макет, list_item_navigation, который содержит только ImageView и TextView.