自定义ActionBar溢出菜单

时间:2014-11-06 09:29:03

标签: android android-actionbar

我试图制作一个ActionBar菜单OverFlow。 twitter的类型。其中名称和用户名显示在OverFlow上的第一个项目上。所以,我这样做了,但它没有起任何作用,任何帮助都会受到赞赏。有我的代码:

MyActivity.java

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    MenuItem menuItem = menu.findItem(R.id.username);
    View usname = getLayoutInflater().inflate(R.layout.action_menu_overflow, null);
    TextView uName = (TextView) usname.findViewById(R.id.profileName);
    TextView slug = (TextView) usname.findViewById(R.id.slugName);
    uName.setText("Users");
    slug.setText("Tracer");
    menuItem.setActionView(usname);
    //MenuItemCompat.setActionView(menuItem, usname);

    //menuItem.setTitle("Users");
    return super.onPrepareOptionsMenu(menu);
}

menu.xml文件

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">

    <item
        android:id="@+id/username"
        android:title="@string/username"
        app:showAsAction="never" />

    <item
        android:id="@+id/logout"
        android:title="@string/logout"
        app:showAsAction="never" />
</menu>

action_menu_overflow.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/slugLayout">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:text="New Text"
        android:id="@+id/profileName" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:layout_marginLeft="15dp"
        android:text="New Text"
        android:id="@+id/slugName" />
</LinearLayout>

Twitter Menu OverFlow

2 个答案:

答案 0 :(得分:1)

这不能通过使用PopUpMenu来实现,这是普通的android溢出菜单使用的,因为它被限制为不容易与复杂的自定义布局/适配器一起使用。但是,这个类似twitter的溢出菜单可以通过使用ListPopupWindow轻松实现,它可以轻松地与更复杂的布局/适配器一起使用。

为简单起见,您可以在activity / fragment中设置一个函数来设置ListPopupWindow。这是一个例子:

public void onListPopUp(View anchor)
    {
        // This a sample dat to fill our ListView
        ArrayList<Person> personItem = new ArrayList<Person>();
        personItem.add(new Person(R.drawable.remove_placeholder_userpic, "Mamluki", "@DigitalSurgeonR"));
        personItem.add(new Person(0, "Lists", "@Lists"));
        personItem.add(new Person(0, "Drafts", "@Drafts"));
        personItem.add(new Person(0, "Accounts", "@Accounts"));
        // Initialise our adapter
        ListPopupWindowAdapter mListPopUpAdapter = new ListPopupWindowAdapter(this, personItem);

        //Initialise our ListPopupWindow instance
        final ListPopupWindow pop = new ListPopupWindow(this);
        // Configure ListPopupWindow properties
        pop.setAdapter(mListPopUpAdapter);
        // Set the view below/above which ListPopupWindow dropdowns
        pop.setAnchorView(anchor);
        // Setting this enables window to be dismissed by click outside ListPopupWindow
        pop.setModal(true);
        // Sets the width of the ListPopupWindow
        pop.setContentWidth(150);
        // Sets the Height of the ListPopupWindow
        pop.setHeight(ListPopupWindow.WRAP_CONTENT);
        // Set up a click listener for the ListView items
        pop.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                // Dismiss the LisPopupWindow when a list item is clicked
                pop.dismiss();
                Toast.makeText(MainActivity.this, "Clicked ListPopUp item " + ((Person) adapterView.getItemAtPosition(position)).getName(), Toast.LENGTH_LONG).show();
            }
        });
        pop.show();
    } 

可以从下面的方法覆盖调用此函数 - :

  @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch (item.getItemId())
        {
            case R.id.action_overflow:
                // Works as long as list item is always visible and does not go into the menu overflow
                final View menuItemView = findViewById(R.id.action_overflow);
                onListPopUp(menuItemView);
                Log.w(LOG_TAG, "You called me OverFlow");

                return true;
            default:
            {
                return super.onOptionsItemSelected(item);
            }
        }
    }

我们的适配器将扩展BaseAdapter,并将包含以下代码段。

public class ListPopupWindowAdapter extends BaseAdapter {

    // ----------------------------------------
    // Variables
    // ----------------------------------------
    private Context context;
    private ArrayList<Person> personItem;
    // ----------------------------------------
    // Methods
    // ----------------------------------------

    public ListPopupWindowAdapter(Context context, ArrayList<Person> personItem)
    {
        this.context = context;
        this.personItem = personItem;
    }

    // ----------------------------------------

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

        ImageView profilePic;
        TextView name;
        TextView userName;
        boolean isWithPicture = (personItem.get(position).getProfilePic() != 0);

            // Small List View , no need to recycle views
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            // Is this the row with the p.picture
            if(isWithPicture)
            {
                //Layout for the top row with profile picture /Avatar
                convertView = inflater.inflate(R.layout.toolbar_overflow_item_row, parent, false);

                profilePic = (ImageView) convertView .findViewById(R.id.imageProfilePic);
                profilePic.setImageResource(personItem.get(position).getProfilePic());

                userName = (TextView) convertView .findViewById(R.id.textUsername);
                userName.setText(personItem.get(position).getUserName());
            }
            else
            {
                //Layout for the other layout without an images
                convertView = inflater.inflate(R.layout.toolbar_overflow_item_row_text, parent, false);
            }


        name = (TextView) convertView .findViewById(R.id.textViewName);
        name.setText(personItem.get(position).getName());


        return convertView ;
    }


    // ----------------------------------------
    //  Implemented
    // ----------------------------------------
    @Override
    public Object getItem(int index)
    {
        return personItem.get(index);
    }

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

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

}

我们有两种布局。一个用于listView顶行项,另一个用于其他行。

toolbar_overfow_row_item.xml -top row item

<?xml version="1.0" encoding="utf-8"?> <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:padding="6dp">

    <ImageView
        android:id="@+id/imageProfilePic"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:visibility="visible"
        android:src="@color/apptheme_accent_teal" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingLeft="16dp"
        >

        <TextView
            android:id="@+id/textViewName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Mamluki"
            android:textColor="@android:color/black"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/textUsername"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="visible"
            android:paddingTop="6dp"

            android:text="\@DigitalSurgeonR"
            android:textColor="?android:attr/textColorSecondary"
            android:textSize="13sp" />

    </LinearLayout> </LinearLayout>

toolbar_overfow_row_item_text.xml 其他行项目

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:padding="14dp">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <TextView
            android:id="@+id/textViewName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Mamluki"
            android:textColor="@android:color/black"
            android:textSize="16sp" />


    </LinearLayout>
</LinearLayout>

此外,要设置ListPopupWindow

的位置

我们可以使用方法: -

 setVerticalOffset(int offset)
 setHorizontalOffset(int offset)

水平&amp;垂直偏移默认为0。将垂直偏移设置为 setVerticalOffset(-36)会使 ListPopupWindow 覆盖操作栏/工具栏。更负面的价值推动它进一步上涨。或者,您可以在 styles.xml 中将其设置为样式,如下所示

    <style name="AppThemeToolBar" parent="AppBaseThemeNoActionBar.Dark" >
            <!-- Customize your theme here. -->
    <!-- ListPopUpWindow styles -->
            <item name="listPopupWindowStyle">@style/Widget.App.ListPopupWindow</item>
        </style>

<!-- Widget styles -->
    <style name="Widget" />

    <style name="Widget.App" parent="Widget" />
    <!-- Widget ListPopUpWindow Style-->
        <style name="Widget.App.ListPopupWindow" parent="Widget.AppCompat.Light.ListPopupWindow">
            <item name="android:dropDownVerticalOffset">-36px</item>
        </style>

答案 1 :(得分:0)

它无法正常工作,因为您正在为菜单项设置actionView,但此项永远不会显示为操作:app:showAsAction="never"所以不幸的是你不能这样做(如果你设置了)这个到ifRoom您将在操作栏中显示自定义布局。

要显示个人资料名称,您可以使用setTitle,但不会有自定义布局。

我还没有找到如何自定义ActionBar下拉菜单项而无需为ActionBar创建自定义视图,并为下拉菜单创建PopupMenu ...