android - 自定义 ActionBar 溢出菜单

标签 android android-actionbar

我正在尝试制作一个 ActionBar 菜单 OverFlow。推特的类型。名称和用户名显示在 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);
}

菜单.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

最佳答案

这不能通过使用 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 并将具有以下代码 fragment 。

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 - 顶行项目

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

水平和垂直偏移量默认为 0。将垂直偏移设置为 setVerticalOffset(-36) 会使 ListPopupWindow 覆盖 actionbar/toolbar 。负值越多,越往上推。或者,您可以将其设置为 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>

关于android - 自定义 ActionBar 溢出菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26775840/

相关文章:

Android 的 RGBToHSV 方法不起作用

java - 使用 Retrofit 2 将 JSON 数据解析为 Horizo​​ntalScrollView

android - 强制用户在 SearchView 中输入数字

android - 在没有菜单按钮的情况下启动 ICS 模拟器

android - 扩展类 Activity

android - 使用应用程序上下文而不是 Activity 上下文

java - 正则表达式禁止文件名中出现字符

Android ActionBar (Sherlock) - 更改菜单图标颜色/透明度

android - 操作栏 - ifRoom 选项留下太多空间

Android ActionBar Action 项