4

基本的に、ユーザーがグリッド ビューのセルを短くクリックまたは長くクリックしたときに、別のコンテキスト メニューを表示したいと考えています。私が抱えている問題は、ユーザーが短くクリックすると OnItemClick リスナーが呼び出され、デバッガーがコンテキスト メニューを表示するコードに到達するのを確認できますが、そこから onCreateContextMenu に移動するのではなく、onItemLongClick に移動します。

私はブール値を使用して長いクリックコードが実行されないようにしようとしましたが、これが実行されても onCreateContextMenu はまったく呼び出されません。

onItemLongClick リスナーを削除すると、短いクリック リスナーが正しく機能し、コンテキスト メニューが正しく表示されます。

他の人がこれと同様の質問をしたことは知っていますが、まだうまくいく解決策を見つけることができませんでした. 誰かがこれを解決したり、正しい方向に向けたりできる場合は、お知らせください。事前に感謝します。報奨金は、私を正しい方向に向けることさえできる人に授与されます.

これは、リスナーのコードの簡略化されたバージョンです。

        mTGrid.setOnItemClickListener(new OnItemClickListener() {
            //this listener should show the context menu for a short click on the gridview.
            @Override
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                    mRequiredMenu = "standard";
                    parent.showContextMenuForChild(v);      

            }
        });

        mTGrid.setOnItemLongClickListener(new OnItemLongClickListener() {
            //this listener should show the context menu for a long click on the gridview.
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
                    mRequiredMenu = "options";
                        parent.showContextMenuForChild(v);      

            }
        });
4

5 に答える 5

7

GridView 項目の短いクリックと長いクリックで異なるコンテキスト メニューを表示したいということは理解しています。

まず、デフォルトの動作では長いクリックでコンテキスト メニューが自動的に表示されるため、短いクリックのリスナーを設定する必要があります。

次に、OnItemClickListener でブール値フラグを true に設定します。長いクリックのデフォルト値は false です。

最後に、onCreateContextMenu() で短いクリックかどうかを確認し、別のコンテキスト メニュー (標準) を表示して、フラグを false に設定します。それ以外の場合は、デフォルトのコンテキスト メニュー (オプション) を表示します。

このアイデアを示すコードを次に示します。

public class MainActivity extends Activity {

    private static final String[] arr = {"A", "B", "C", "D", "E", "F", "G", "H","I"};

    private GridView mTGrid;
    private boolean isShort;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mTGrid = (GridView) findViewById(R.id.gridView1);
        registerForContextMenu(mTGrid);

        mTGrid.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                isShort = true;
                openContextMenu(view);
            }
        });

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.cell, arr);
        mTGrid.setAdapter(adapter);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;

        if(isShort) {
            getMenuInflater().inflate(R.menu.context_standard, menu);
            menu.setHeaderTitle("Standard Menu for "+arr[info.position]);
            isShort = false;
        }
        else {
            getMenuInflater().inflate(R.menu.context_options, menu);
            menu.setHeaderTitle("Options Menu for "+arr[info.position]);
        }
    }   
}

サンプル アプリケーション: サンプル アプリケーションをダウンロードして動作を確認できます。GridExample_eclipse_project

于 2013-04-06T06:32:40.687 に答える
0
mTGrid.setOnItemClickListener(new OnItemClickListener() {
            //this listener should show the context menu for a short click on the gridview.
            @Override
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                     clickFlag=true;   
                     mRequiredMenu = "standard";                     

            }
        });

        mTGrid.setOnItemLongClickListener(new OnItemLongClickListener() {
            //this listener should show the context menu for a long click on the gridview.
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
                     clickFlag=false;
                     mRequiredMenu = "options";                  
            }
        });

if(clickFlag){        
    if(mRequiredMenu.equals("standard");{
        //just click event
        parent.showContextMenuForChild(v);
    }else{}
}else{
   if(mRequiredMenu.equals("options");{
        //just Long click event
        parent.showContextMenuForChild(v);
    }else{} 

}
于 2013-04-06T04:49:52.590 に答える
0

OnItemLongClickListenerのコンテキストメニューを表示するListViewと、そのリスナーを介してそうしようとするため、トリガーされます。からのコードは次のAbsListViewとおりです。

@Override
public boolean showContextMenuForChild(View originalView) {
    final int longPressPosition = getPositionForView(originalView);
    if (longPressPosition >= 0) {
        final long longPressId = mAdapter.getItemId(longPressPosition);
        boolean handled = false;

        if (mOnItemLongClickListener != null) {
            handled = mOnItemLongClickListener.onItemLongClick(AbsListView.this, originalView,
                    longPressPosition, longPressId);
        }
        if (!handled) {
            mContextMenuInfo = createContextMenuInfo(
                    getChildAt(longPressPosition - mFirstPosition),
                    longPressPosition, longPressId);
            handled = super.showContextMenuForChild(originalView);
        }

        return handled;
    }
    return false;
}

このことから、ifmOnItemLongClickListener.onItemLongClickが true を返す場合、それは呼び出しが処理され、メソッドが終了したことを意味することがわかります。false が返された場合は、コンテキスト メニューを作成しようとします。

onItemLongClickしたがって、 (コードが表示されていない)の return ステートメントを変更して、実際に長くクリックされた場合はtrueを返し、クリックされただけの場合はfalseを返す必要があります。

mTGrid.setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {

        mRequiredMenu = "standard";
        mItemClicked = true;
        parent.showContextMenuForChild(v);
    }
});

mTGrid.setOnItemLongClickListener(new OnItemLongClickListener() {

    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {

        if(mItemClicked) {
            mItemClicked = false;
            return false;
        }

        mRequiredMenu = "options";
        parent.showContextMenuForChild(v);
        return true;
    }
});
于 2013-04-07T10:47:31.080 に答える
0

絶望的な状況の絶望的な解決策。

1.リスナー内でコードを実行する代わりに、ブール値を使用してみてください。

 mTGrid.setOnItemClickListener(new OnItemClickListener() {
        //this listener should show the context menu for a short click on the gridview.
        @Override
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                b=true     
        }
    });

    mTGrid.setOnItemLongClickListener(new OnItemLongClickListener() {
        //this listener should show the context menu for a long click on the gridview.
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
                b=false      
        }
    });
if(b)
{
     mRequiredMenu = "standard";
     parent.showContextMenuForChild(v);  
}
else
{
    mRequiredMenu = "options";
    parent.showContextMenuForChild(v);
}

2 クリック可能なプロパティと longclickable のプロパティの両方がレイアウトで「true」であるかどうかを確認します。

于 2013-04-04T13:23:40.023 に答える