다중 조각 활동에서 onContextItemSelected를 처리하는 방법은 무엇입니까?
현재 Android 1.6 사용자에게도 프래그먼트 사용의 이점을 제공하기 위해 "Android v4 용 호환성 라이브러리"를 사용하도록 내 애플리케이션을 조정하려고합니다.
상황에 맞는 메뉴의 구현은 까다로운 것 같습니다.
- 애플리케이션의 주요 활동은 FragmentActivity 클래스를 확장하는 것 입니다.
- 프래그먼트는 모두 Fragment 클래스를 확장하는 하나의 클래스를 기반으로합니다.
- 조각 클래스는 onCreateView () 메서드 에서 registerForContextMenu () 를 호출 하고 onCreateContextMenu () 및 onContextItemSelected () 메서드를 재정의합니다 .
들어 인, onCreateContextMenu () 이 꽤 잘 작동합니다. 컨텍스트 메뉴는 리소스 파일에서 부풀려지고 선택한 항목에 따라 약간 수정됩니다 (조각이 ListFragment가 아닌 경우에도 listView ... 기반).
상황에 맞는 메뉴 항목을 선택하면 문제가 발생합니다. onContextItemSelected () 는 처음 추가 된 조각부터 시작하여 현재 존재하는 모든 조각에 대해 호출됩니다.
제 경우에는 조각이 폴더 구조의 내용을 표시하는 데 사용됩니다. 하위 폴더 조각의 컨텍스트 메뉴가 열리고 메뉴 항목이 선택되면 먼저 상위 수준 에서 onContextItemSelected () 가 호출됩니다 (현재 허용 / 표시되는 조각 수에 따라 다름).
지금은 onCreateContextMenu ()를 호출하는 마지막 조각의 태그를 보유하는 활동 수준의 필드에서 해결 방법을 사용합니다 . 이렇게 하면 저장된 태그가 getTag ()와 동일하지 않을 때 onContextItemSelected () 시작 부분에서 "return super.onContextItemSelected (item)"를 호출 할 수 있습니다 . 그러나이 접근법은 나에게 약간 더러워 보입니다.
모든 조각에서 onContextItemSelected ()가 호출되는 이유는 무엇입니까? 그리고 onCreateContextMenu ()를 호출 한 것뿐만 아니라 ?
이것을 처리하는 가장 우아한 방법은 무엇입니까?
비슷한 문제를 방금 처리했기 때문에 해결 방법을 찾았더라도 답변을 게시하겠습니다. 특정 조각에 대한 컨텍스트 메뉴를 확장 할 때 각 메뉴 항목에 조각에 고유 한 groupId를 할당합니다. 그런 다음 'onContextItemSelected'에서 groupId를 테스트합니다. 예를 들면 :
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
menu.add(UNIQUE_FRAGMENT_GROUP_ID, MENU_OPTION_1, 0, R.string.src1);
menu.add(UNIQUE_FRAGMENT_GROUP_ID, MENU_OPTION_2, 0, R.string.src2);
}
public boolean onContextItemSelected(MenuItem item) {
//only this fragment's context menus have group ID of -1
if (item.getGroupId() == UNIQUE_FRAGMENT_GROUP_ID) {
switch(item.getItemId()) {
case MENU_OPTION_1: doSomething(); break;
case MENU_OPTION_2: doSomethingElse(); break;
}
}
이렇게하면 모든 조각이 여전히 'onContextItemSelected'에 대한 호출을 수신하지만 올바른 조각 만 응답하므로 활동 수준 코드를 작성할 필요가 없습니다. 이 기술의 수정 된 버전은 'menu.add (...)'를 사용하지 않아도 작동 할 수 있다고 가정합니다.
또 다른 해결책 :
@Override
public boolean onContextItemSelected(MenuItem item) {
if (getUserVisibleHint()) {
// context menu logic
return true;
}
return false;
}
Jake Wharton 의이 패치 를 기반으로 합니다 .
Sergei G (Jake Wharton 수정 기반)의 간단한 솔루션이 마음에 들었지만 여러 조각에 추가하는 것이 더 쉽기 때문에 반전되었습니다.
public boolean onContextItemSelected(android.view.MenuItem item)
{
if( getUserVisibleHint() == false )
{
return false;
}
// The rest of your onConextItemSelect code
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
}
그 후, 이전과 동일한 코드.
아주 쉬운 해결책을 찾았습니다. ContextMenu가 생성 될 때마다 onCreateContextMenu ()가 호출되므로 부울 변수를 true로 설정합니다.
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.film_menu, menu);
bMenu=true;
}
내가해야 할 유일한 다른 일은 해당 변수 OnContextItemSelected ()를 요청하는 것입니다.
public boolean onContextItemSelected(MenuItem item) {
if (bMenu) {
bMenu=false;
if (item.getItemId() == R.id.filmProperties) {
///Your code
return true;
} else {
return super.onContextItemSelected(item);
}
} else {
return super.onContextItemSelected(item);
}
}
그게 다야.
대안을 찾았습니다. 위의 내 문제에 대해 아무것도 변경하지 않지만 의미가 없습니다.
내 응용 프로그램에서 컨텍스트 메뉴를 완전히 제거했습니다. 대신 목록 항목을 길게 클릭하고이 순간 작업 표시 줄의 보이는 버튼을 변경합니다. 사용자 관점에서 이것은 컨텍스트 메뉴와 같은 훨씬 더 태블릿입니다.
이전 버전과 호환되는 응용 프로그램에서는 작업 표시 줄이 없습니다. 그래서 저는 Honeycomb 이전의 장치를 위해 나만의 도구 모음을 만들기로 결정했습니다.
상황에 맞는 메뉴를 계속 사용하고 싶다면 위에서 언급 한 해결 방법으로 더 나은 솔루션을 찾지 못했습니다.
내 첫 번째 조각에서는 모든 메뉴 ID> 5000을 설정 했으므로 첫 번째 조각의 onContextItemSelected 코드의 첫 번째 줄로
if (item.getItemId() < 5000) return false;
두 번째 조각이 호출됩니다.
조각에 목록보기가있는 어댑터를 사용하는 경우 도움이 될 수 있습니다.
public boolean onContextItemSelected(final MenuItem item) {
final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
//Check if the context menu call came from the list in this fragment (needed for support for multiple fragments in one screen)
if (info.targetView.getParent() != getView().findViewById(android.R.id.list))
return super.onContextItemSelected(item);
//Handle context menu item call
switch (item.getItemId()) {
...
}
}
그냥 바꿔
@Override
public boolean onContextItemSelected(MenuItem item) {
return true;
}
...에
@Override
public boolean onContextItemSelected(MenuItem item) {
return super.onContextItemSelected(item);
}
그리고 훌륭하게 작동합니다 !!!
IMHO 우리는 대상 뷰가 조각 목록 뷰의 자식인지 확인할 수 있습니다. 매우 간단하고 잘 작동합니다. 방금 모든 조각에 추가했습니다. if (getListView.getPositionForView(info.targetView) == -1) return false이전 API에서 마이그레이션 할 때
이것은 내 부모 조각 중 하나의 예입니다. 이것은 Scala이지만 아이디어가 있으 셨기를 바랍니다.
@Loggable
override def onContextItemSelected(menuItem: MenuItem): Boolean = {
for {
filterBlock <- TabContent.filterBlock
optionBlock <- TabContent.optionBlock
environmentBlock <- TabContent.environmentBlock
componentBlock <- TabContent.componentBlock
} yield menuItem.getMenuInfo match {
case info: AdapterContextMenuInfo =>
if (getListView.getPositionForView(info.targetView) == -1)
return false
TabContent.adapter.getItem(info.position) match {
case item: FilterBlock.Item =>
filterBlock.onContextItemSelected(menuItem, item)
case item: OptionBlock.Item =>
optionBlock.onContextItemSelected(menuItem, item)
case item: EnvironmentBlock.Item =>
environmentBlock.onContextItemSelected(menuItem, item)
case item: ComponentBlock.Item =>
componentBlock.onContextItemSelected(menuItem, item)
case item =>
log.debug("skip unknown context menu item " + info.targetView)
false
}
case info =>
log.fatal("unsupported menu info " + info)
false
}
} getOrElse false
P.S. If you trace calls of onContextItemSelected(...) you may notify that super.onContextItemSelected(item) return always false. Valid onContextItemSelected invoked AFTER, not WITHIN. So super.onContextItemSelected(item) is useless and I replaced it with false.
I found an easier solution than the exposed:
public boolean onContextItemSelected(MenuItem item) {
ListView yourList = (ListView) (ListView) getView().findViewById(R.id.yourList);
if (!yourList.hasFocus())
return false;
switch(item.getItemId()) {
...
}
}
In the method changed return true; to return super.onContextItemSelected(item); in my onContextItemSelected() override and everything started working.
'Program Club' 카테고리의 다른 글
| 라디오 버튼 그룹의 값 가져 오기 (0) | 2020.11.07 |
|---|---|
| com.sun.jdi.InvocationException이 메서드를 호출하는 동안 발생했습니다. (0) | 2020.11.07 |
| PowerShell을 사용하여 .sql 파일을 실행하는 방법은 무엇입니까? (0) | 2020.11.07 |
| ToString ( "X2")의 의미는 무엇입니까? (0) | 2020.11.07 |
| Maven이 인코딩에 대해 경고하는 이유는 무엇입니까? (0) | 2020.11.07 |