【问题标题】:How to do popup menus on button clicked with labeled icons?如何在单击带有标签图标的按钮上弹出菜单?
【发布时间】:2016-06-07 15:35:30
【问题描述】:

我正在尝试按照指南实现这一目标:

基本上我想要这样的东西:

我想让它出现在弹出窗口中,就像文档中的弹出窗口一样。

当用户单击“视图”时,将出现一个自定义视图,其中显示更多选项。我正在为PopupWindow 创建一个自定义布局,但它没有给我想要的结果。我正在创建一个简单的颜色选择器,它只允许用户选择 8 种颜色。我尝试膨胀包含RecyclerView 的布局,但它看起来像这样:

我知道这是不可能的,但是有没有人能够实现“Google”在他们的指南上宣传的内容?我相信这是不可能的,但许多应用程序都能做到。

这是我如何实例化弹出窗口的代码:

private void showChooseColorPopup()
{
    /*
    PopupMenu popup = new PopupMenu(this, mBottomMenuPanelLinearLayout);
    MenuInflater inflater = popup.getMenuInflater();
    inflater.inflate(R.menu.menu_note_color, popup.getMenu());
    popup.show();
    */

    LayoutInflater inflater = LayoutInflater.from(this);
    View view = inflater.inflate(R.layout.layout_popup_menu_note_color , null);

    NoteColorSelectionAdapter adapter = new NoteColorSelectionAdapter(this, NotifireID.colors);
    adapter.setOnColorSelected(this);

    GridLayoutManager layoutManager = new GridLayoutManager(this , 3);
    layoutManager.setOrientation(GridLayoutManager.HORIZONTAL);

    RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview_popup_menu_note_color);
    recyclerView.setAdapter(adapter);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(layoutManager);

    // TODO Use Dialog instead

    PopupWindow popupWindow = new PopupWindow(view, RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    popupWindow.setBackgroundDrawable(ContextCompat.getDrawable(this, R.drawable.ic_white));

    int location[] = new int[2];
    mColorButton.getLocationOnScreen(location);
    popupWindow.showAtLocation(mColorButton, Gravity.NO_GRAVITY, location[0] , location[1] - mColorButton.getHeight());
    // popupWindow.show(mColorButton);
}

这是我的 GridView 适配器:

package com.neonwarge.android.notifire.adapter;

import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;

import com.neonwarge.android.notifire.R;

import java.util.ArrayList;

public class NoteColorSelectionAdapter extends RecyclerView.Adapter<NoteColorSelectionAdapter.ViewHolder>
{
    private final static int COUNT = 8;
    private ArrayList<Integer> mColors;
    private Context mContext;
    private OnColorSelected mOnColorSelected;

    public interface OnColorSelected
    {
        public void onColorSelected(View v, int position, int color);
    }

    public NoteColorSelectionAdapter(Context context , ArrayList<Integer> noteColors)
    {
        mColors = noteColors;
        mContext = context;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        LayoutInflater inflater = LayoutInflater.from(mContext);

        View view = inflater.inflate(R.layout.listitem_popup_menu_note_color, parent, false);

        NoteColorSelectionAdapter.ViewHolder viewHolder = new NoteColorSelectionAdapter.ViewHolder(view);

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position)
    {
        int selectedColor = mColors.get(position);
        final int p = position; final int color = selectedColor;

        switch(selectedColor)
        {
            case R.color.yellow:
                holder.mColorImageButton.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_yellow));
                break;

            case R.color.orange:
                holder.mColorImageButton.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_orange));
                break;

            case R.color.purple:
                holder.mColorImageButton.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_purple));
                break;

            case R.color.red:
                holder.mColorImageButton.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_red));
                break;

            case R.color.pink:
                holder.mColorImageButton.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_pink));
                break;

            case R.color.skyblue:
                holder.mColorImageButton.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_skyblue));
                break;

            case R.color.brown:
                holder.mColorImageButton.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_brown));
                break;

            case R.color.green:
                holder.mColorImageButton.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_green));
                break;
        }

        holder.mColorImageButton.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if(mOnColorSelected != null)
                    mOnColorSelected.onColorSelected(v, p, color);
            }
        });
    }

    @Override
    public int getItemCount()
    {
        return COUNT;
    }

    public void setOnColorSelected(OnColorSelected i)
    {
        mOnColorSelected = i;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder
    {
        public ImageButton mColorImageButton;

        public ViewHolder(View view)
        {
            super(view);

            mColorImageButton = (ImageButton) view.findViewById(R.id.imagebutton_color_note);
        }
    }
}

这是我的 layout_popup_menu_note_color:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview_popup_menu_note_color"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</RelativeLayout>

这是我检查的链接,它们都不适合我。除了反射 hack,因为我还没有尝试过。

PopupWindow in android

Set own layout in popup window in android

How to define layout in a PopupWindow from an xml file, when PopupWindow method is called from a separate class

PopupMenu 适合我,但我想要图标。我知道这是不可能的。但我不敢苟同,我看到的很多应用程序的布局上都有一个按钮,我单击它,然后会出现一个PopupWindow,使按钮看起来像一个菜单下拉列表。

我这样做的原因是如您所见,我的底部面板菜单只是一个自定义布局。我创建了一个自定义标签按钮,我希望在单击它时弹出一个菜单。

谢谢!

【问题讨论】:

  • 嗨 Neon,你能把 recyclerview_popup_menu_note_color 的 xml 贴出来吗?
  • @KarenForde 你好,Karen,请看我的编辑,文件名是layout_popup_menu_note_color。这就是recyclerview_popup_menu_note_color located。谢谢!
  • 感谢您发布 xml。请在下面查看我建议的答案,如果有帮助,请告诉我:)

标签: android android-layout android-gridview


【解决方案1】:

我认为您看到的主要问题是因为您已将 PopupWindow 的 RelativeLayout 设置为:

android:layout_width="match_parent"
android:layout_height="match_parent"

这就是为什么您的图标在整个视图中被拉长,所以看起来不像是一个弹出窗口。

尝试更改为以下内容,看看是否有帮助:

   android:layout_width="wrap_content"
   android:layout_height="wrap_content"

【讨论】:

  • 谢谢!不幸的是,它并不能解决问题。我认为我的方法彼此不兼容。它的行为不像菜单。我想我会放弃这个想法并坚持对话。
  • @Neon - 抱歉,很难准确地想象您想要实现的目标。看起来您希望颜色方块出现在弹出窗口上(我认为它是图像中间的白色方块。看起来颜色布局填满了整个屏幕,所以我认为移动到 wrap_content 至少会让您更接近您想要实现的目标。如果您想创建一个图像来准确显示您希望它的样子,以及使用 wrap_content 的另一个外观,我很乐意尝试在其中运行您的代码示例项目,看看我是否可以为您修复它。
  • 嗨@KarenForde 抱歉回复晚了,请看我的编辑。谢谢!
  • 嗨@NeonWarge 尝试在上面缺少代码的地方使用一些值来运行您的代码,但我得到 android.view.InflateException: Binary XML file line #11: RecyclerView has no LayoutManager for线 View view = inflater.inflate(R.layout.layout_popup_menu_note_color , null);你能发布完整的 xml 或代码来阻止你吗?还有包含 imagebutton_color_note 的布局。谢谢!
  • 另外给你一个提示,我尝试使用对话框运行相同的东西。猜猜看,同样的行为,看起来 RecyclerView 没有“包裹”它的高度和宽度将随着屏幕大小而拉伸。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-16
  • 1970-01-01
相关资源
最近更新 更多