web-dev-qa-db-ja.com

Material Design Androidでこのカスタムポップアップメニューを実現する方法は?

Twitter in Android for itemのようなカスタムポップアップメニューを実現したいと画像が、私はそのために使用されるコンポーネントが何であるかわかりません。

Material Design Webサイトで、グーグルプレゼント このソリューション 。だから私は、これを達成するためのネイティブソリューションがあると思います。

enter image description here

ポップアップメニュー で試しましたが、このビューのレイアウトをそのようにカスタマイズする方法が見つかりません。

25
lopez.mikhael

ListPopupWindow を使用して、カスタムアダプタを送信し、ListPopupWindowの各行のレイアウトを制御できます。通常のPopupWindowに関しては、アンカービューを提供する必要があり、さらにsetContentWidthのインスタンスでListPopupWindowを呼び出す必要があります。これにより、ポップアップウィンドウの幅がコンテンツのサイズ。それはあなたが支払わなければならない小さな価格ですが、小さなデータセットにとっては大したことではありません。行の最大幅を取得するこのユーティリティメソッドがあります。

public int measureContentWidth(ListAdapter adapter) {
    int maxWidth = 0;
    int count = adapter.getCount();
    final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    View itemView = null;
    for (int i = 0; i < count; i++) {
        itemView = adapter.getView(i, itemView, this);
        itemView.measure(widthMeasureSpec, heightMeasureSpec);
        maxWidth = Math.max(maxWidth, itemView.getMeasuredWidth());
    }
    return maxWidth;
}
25
Blackbelt

PopupMenuというウィジェットがあります。これは基本的に特定のビューに固定されたメニューです。 1つの欠点は、デフォルトでアイコンが表示されないことです。

ただし、リフレクションを使用し、setForceShowIconを呼び出してそれらを明らかにすることができます。必要なコードは次のとおりです。

  • PopupMenuは特定のビューに固定されているため、ActionBarアイテムにはactionLayout属性があります。そのレイアウト(action_item.xml)は次のように単純にすることができます。

    <Button
        xmlns:Android="http://schemas.Android.com/apk/res/Android"
        style="?attr/actionButtonStyle"
        Android:layout_gravity="center"
        Android:text="Show popup"
        Android:textStyle="bold"
        Android:textSize="12sp"
        Android:layout_width="wrap_content"
        Android:layout_height="match_parent"/>
    
  • ActionBar上記のレイアウトのアイテムを含むメニュースタイル

    <menu
        xmlns:Android="http://schemas.Android.com/apk/res/Android">
        <item
            Android:id="@+id/popup_item"
            Android:title="Show popup"
            Android:showAsAction="always"
            Android:actionLayout="@layout/action_item"/>
    </menu>
    
  • きみの popup_menu.xmlPopupMenu用に膨張させるレイアウト

    <menu
        xmlns:Android="http://schemas.Android.com/apk/res/Android">
        <item
            Android:id="@+id/item1"
            Android:title="Item1"
            Android:icon="@mipmap/ic_launcher"/>
    </menu>
    
  • 最後に、ActionBarアイテムがクリックされたときにインフレーションを実行するコード

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_add_item:
                PopupMenu popup = new PopupMenu(this, item.getActionView());
                MenuInflater inflater = popup.getMenuInflater();
                inflater.inflate(R.menu.popup_menu, popup.getMenu());
    
                // Use reflection to invoke setForceShowIcon
                try {
                    Field[] fields = popup.getClass().getDeclaredFields();
                    for (Field field : fields) {
                        if ("mPopup".equals(field.getName())) {
                            field.setAccessible(true);
                            Object menuPopupHelper = field.get(popup);
                            Class<?> classPopupHelper = Class
                                    .forName(menuPopupHelper.getClass().getName());
                            Method setForceIcons = classPopupHelper
                                    .getMethod("setForceShowIcon", boolean.class);
                            setForceIcons.invoke(menuPopupHelper, true);
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
                popup.show();
                return true;
        }
    
        return super.onOptionsItemSelected(item);
    }
    

メニューでその複数行のテキストを取得するには、ポップアップメニュー項目にもactionLayoutを使用する必要があることに注意してください。

3
Simas

ポップアップリストフラグメント を使用します。フラグメントの良いところは、簡単に アニメーション化 できることです(フラグメントを理解できない場合は、最初に読むことをお勧めします フラグメントの紹介

ポップアップコンテンツを完全に制御する場合は、 Dialog Fragment を参照してください

3

私は同じ問題を抱えていますが、最終的に自分のソリューションでコードを共有していることがわかりました。それがあなたを助けることを願っています。

popupWindowDogs = popupWindowDogs();
    button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            // popupWindowDogs.showAsDropDown(v, -5, 0);
            popupWindowDogs().showAtLocation(v, Gravity.CENTER, 0, 0);
        }
    });
    // Detect touched area
    detector = new SimpleGestureFilter(this, this);

}

public PopupWindow popupWindowDogs()
{

    // initialize a pop up window type
    PopupWindow popupWindow = new PopupWindow(this);

    // the drop down list is a list view
    final ListView listView = new ListView(this);
    // set our adapter and pass our pop up window contents
    listView.setAdapter(dogsAdapter(popUpContents));
    // listView.setBackgroundColor(Color.DKGRAY);
    listView.setBackgroundResource(R.drawable.ss4);
    listView.setPadding(0, 0, 0, 10);
    listView.setDivider(null);
    try {

        listView.setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                View c = listView.getChildAt(0);
                String cc = listView.getChildAt(0).toString();
                int scrolly = -c.getTop() + listView.getFirstVisiblePosition() * c.getHeight();
                /*
                 * Toast.makeText(getApplicationContext(), scrolly + "", Toast.LENGTH_SHORT)
                 * .show();
                 */}

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                    int totalItemCount) {

            }
        });
    } catch (Exception e) {
        Toast.makeText(getApplicationContext(), e.toString() + "", Toast.LENGTH_SHORT)
                .show();
    }
    listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View v, int arg2,
                long arg3) {
            try {

                // TODO Auto-generated method stub
                Context mContext = v.getContext();
                Swipetouch mainActivity = ((Swipetouch) mContext);
                // add some animation when a list item was clicked
                Animation fadeInAnimation = AnimationUtils.loadAnimation(v.getContext(),
                        Android.R.anim.fade_in);
                fadeInAnimation.setDuration(10);
                v.startAnimation(fadeInAnimation);
                // dismiss the pop up
                mainActivity.popupWindowDogs.dismiss();
                // get the text and set it as the button text
                String val = (String) arg0.getItemAtPosition(arg2);
                // Toast.makeText(mContext, val, Toast.LENGTH_SHORT).show();
                if (val.equals("Signup Now")) {
                    Intent ii = new Intent(getApplicationContext(), Registration.class);
                    startActivity(ii);
                    stopService(new Intent(Swipetouch.this, MyService.class));
                    stopService(new Intent(Swipetouch.this, MyService.class));
                } else if (val.equals("Login")) {
                    Intent ii = new Intent(getApplicationContext(), MyLoginActivity.class);
                    startActivity(ii);
                    stopService(new Intent(Swipetouch.this, MyService.class));

                } else if (val.equals("Exit")) {
                    finish();
                    stopService(new Intent(Swipetouch.this, MyService.class));
                } else if (val.equals("Friends")) {
                    Intent ii = new Intent(getApplicationContext(), MyLoginActivity.class);
                    startActivity(ii);
                } else if (val.equals("Exit")) {
                    stopService(new Intent(Swipetouch.this, MyService.class));
                    finish();
                }

            } catch (Exception e) {
                Toast.makeText(Swipetouch.this, e.toString(), Toast.LENGTH_SHORT).show();
            }
        }

    });
    // some other visual settings
    popupWindow.setFocusable(true);
    popupWindow.setWidth(250);
    // popupWindow.setHeight(300);
    popupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);

    // set the list view as pop up window content
    // SET WALLPAPER IMAGE
    /*
     * popupWindow.setBackgroundDrawable(getWallpaper()); popupWindow.setHeight(300);
     */
    // layout.setBackgroundResource(R.drawable.sshadow);
    // layout.setBackgroundColor(Color.TRANSPARENT);
    // popupWindow.setContentView(layout);

    popupWindow.setBackgroundDrawable(new ColorDrawable(
            Android.graphics.Color.TRANSPARENT));
    popupWindow.setContentView(listView);

    return popupWindow;
}
2
parik dhakan
  try {
                    Java.lang.reflect.Field[] fields = popup.getClass().getDeclaredFields();
                    for (Java.lang.reflect.Field field : fields) {
                        if ("mPopup".equals(field.getName())) {
                            field.setAccessible(true);
                            Object menuPopupHelper = field.get(popup);
                            Class<?> classPopupHelper = Class
                                    .forName(menuPopupHelper.getClass().getName());
                            Method setForceIcons = classPopupHelper
                                    .getMethod("setForceShowIcon", boolean.class);
                            setForceIcons.invoke(menuPopupHelper, true);
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
1
Bilel Bouali

このコードは私のアプリで動作しています。

これを試して :-

<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=".LocationDetailsActivity">


<item xmlns:tools="http://schemas.Android.com/tools"
    Android:icon="@Android:drawable/ic_menu_mapmode"
    app:showAsAction="ifRoom"
    Android:title="@string/title_of_menu"
    tools:context=".LocationDetailsActivity">
    //the menu list with icon
    <menu>
        <item
            Android:id="@+id/action_map_type_normal"
            Android:orderInCategory="100"
            Android:icon="some_icon" //place your icon here
            Android:title="Vacation spots" />
        <item
            Android:id="@+id/action_map_type_satellite"
            Android:orderInCategory="100"
            Android:icon="some_icon" //place your icon here
            Android:title="Friends and family" />
        <item
            Android:id="@+id/action_map_type_hybrid"
            Android:orderInCategory="100"
            Android:icon="some_icon" //place your icon here
            Android:title="Restaurants" />
    </menu>
</item>

これらのさまざまなプロバイダーからチュートリアルを実行できます

http://developer.Android.com/guide/topics/ui/actionbar.html

http://www.vogella.com/tutorials/AndroidActionBar/article.html

http://www.androidhive.info/2013/11/Android-working-with-action-bar/

それらのすべてはあなたを助けるために素晴らしい例とソースコードを持っています

これがあなたを助けることを願っています:)

1
Biswajit

より簡単なソリューション。これを.show()メソッドの直前に追加します。

try {
  Field mFieldPopup=popupMenu.getClass().getDeclaredField("mPopup");
  mFieldPopup.setAccessible(true);
  MenuPopupHelper mPopup = (MenuPopupHelper) mFieldPopup.get(popupMenu);
  mPopup.setForceShowIcon(true);
} catch (Exception e) {}
0
Tommie