it-swarm.com.ru

Добавить иконки в Android Navigation Drawer?

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

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

В проектной документации, а также в ряде популярных приложений, таких как 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's click listener
    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

    ...
}
}

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

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

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

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

17
bean

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

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

Кто-нибудь знает, как добавить значки к элементам Navigation Drawer?

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

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

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

7
CommonsWare

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

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

поставленный 

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

Чтобы структурировать это действительно ясно, я сделал несколько дополнительных строк кода для объектно-ориентированной реализации, которая генерирует все из массива NavigationItems - простого 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;
}

И навигационный адаптер:

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.

2
Cibes

Массив строк не является определяющим расположением строк. Ваш 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;
}

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

2
Neoh