17

에 나는 내 응용 프로그램에서 다음과 같은 구조를 가지고있다. ListView의 각 요소는 LinearLayout이고 두 개의 숫자는 TextViews이고 Button입니다. LinearLayout과 버튼은 onClickListeners (별도)입니다. LinearLayout을 클릭하면 다른 Activity이 시작됩니다. 클릭 동작이 매우 일치하지 않는 것으로 나타났습니다. 즉, 액션이 즉시 실행되지만 매우 자주 지연되고 가끔 몇 번 탭해도 무시됩니다. 내가 탭할 수 있기 때문에 더 이상해질 수 없으며 목록을 스크롤하기 시작할 때만 작업이 실행됩니다. 내가 setFocusable(false)setSelectable(true)의 다양한 조합을 시도했지만 어떤 차이도없는 것 같습니다. 어떤 아이디어? 자세한 내용을 기꺼이 알려 드리겠습니다.안드로이드 지연 클릭은 ListView에

답변

3

아무도 내가 이것을 어떻게 해결했는지 궁금 할 때가 있습니다. 기본적으로 레이아웃을 단순화해야했습니다. 복잡한 중첩 구조가있을 때 이벤트가 너무 오래 걸려 버블 링 될 수 있으며 동시에 스크롤 목록을 시작하면 이벤트가 잘못된 동작을 트리거 할 수 있습니다. 가능한 한 많이 RelativeLayout으로 전환하여 레이아웃을 다듬 었습니다. 많은 도움이 된 것처럼 보입니다.

-1

이벤트 스레드에서 일부 차단 프로세스 (예 : webservices 호출 또는 파일 열기)가 실행되어 이벤트 스레드가 차단 된 것 같습니다. 이 경우 차단 코드를 이벤트 THread 이외의 다른 스레드로 처리하십시오.

+0

저는 모든 백그라운드 프로세스를 수행하기 위해 특별히 AsyncLoader를 사용합니다. 그러나 팁을 주셔서 코드를 재평가 해 보겠습니다! – Bostone

+0

결국 이유가 아니 었습니다. 내 대답을 참조하십시오 – Bostone

4

동일한 문제가 발생했지만 제 경우에는 솔루션이보기에 대한 참조를 유지하지 않아서 ListView의보기에 문제가 발생했습니다. 캐싱. converview를 사용하여 getView() 메소드를 올바르게 구현 한 후에는 손실/예기치 않은 클릭 호출로 인한 이상한 동작이 사라졌습니다.

+0

내 코드에서 핸들러 패턴을 항상 사용합니다. – Bostone

+0

+1을 사용할 수 있습니다. 나는 여기에 들어가지 않을 이유 때문에 하나의 'ListView' 행에 사용 된 내 견해 중 하나에 대한 참조를 유지하고있었습니다 - 어떤 이유로이 활동에 대한 모든 클릭이 해당 항목에 지연되는 효과가있었습니다 * * 모두 다시 흘러서 예외가 발생합니다. 어댑터 내부의 뷰를 작성하면이 문제가 해결됩니다. 매우 이상합니다 – Dori

1

나를 위해 일한 것은 OnItemClickListenerListView에서 setOnItemClickListener까지 할당하는 것이지 개별 목록 항목에 OnClickListener을 할당하는 것이 아닙니다. 당연히 버튼에는 자체적으로 OnClickListener이 필요하지만이 시나리오는 테스트하지 않았습니다.

9

비슷한 문제가있어서 디버깅하고 해결하는 데 2 ​​일이 걸렸습니다. 모든 목록 항목에 대해 LinearLayout에 여러 TextView를 만드는 ListAdapter가 있습니다. 각 항목의 클릭을 처리해야하므로 각 TextView에는 고유 한 OnClickListener가 있습니다.

뷰를 다시 사용하도록 구현을 변경했을 때 OnClickListener가 올바르게 작동하지 않았습니다. 4.4.2에서 대부분의 클릭이 작동했지만 때로는 목록에서 스크롤 할 때까지 아무런 반응이 없었습니다. 2.3에서는 첫 번째 클릭이 작동하지 않고 모든 클릭이 한꺼번에 처리됩니다.

내 특별한 경우에는 리소스를 부 풀리지 않고 자바 코드로 모든 뷰를 만들었습니다. 그리고 중요한 점은 뷰를 재사용 할 때도 LinearLayout의 LayoutParams를 설정했다는 것입니다.이 뷰는 재사용 된 뷰에 올바른 레이아웃 매개 변수가 있다고 가정 할 때 더 안전합니다. 모든 것을 재사용 할 때 LayoutParams를 설정하지 않으면 잘 작동합니다!

public View getView(int position, View convertView, ViewGroup parent) { 
    LinearLayout tapeLine = null; 
    if (convertView != null && convertView instanceof LinearLayout && ((LinearLayout)convertView).getChildCount() == 4) tapeLine = (LinearLayout) convertView; // Reuse view 
    else tapeLine = new LinearLayout(activity); 
    if (convertView == null) { // Don't set LayoutParams when reusing view 
     ViewGroup.LayoutParams tapeLineLayoutParams = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 
     tapeLine.setLayoutParams(tapeLineLayoutParams); 
    } 
    ScrollingTape scrollingTape = calculatorHolder.getCalculator().getScrollingTape(); 
    int tapeWidthPx = parent.getWidth(); 
    TapeLineTextSizeInfo tapeLineTextSizeInfo = calculatorHolder.getTapeLineTextSizeHelper().createTapeLineTextSizeInfo(tapeWidthPx); 
    ScrollingTapeLine line = scrollingTape.getLine(position); 
    tapeLine.setOrientation(LinearLayout.HORIZONTAL); 
    int tapeBackgroundColor = getBackgroundColor(line); 
    tapeLine.setBackgroundColor(tapeBackgroundColor); 
    addColumnViews(tapeLine, line, tapeLineTextSizeInfo); 
    tapeLine.setTag(R.id.scrollingtapeadapter_viewtag_position, position); 
    tapeLine.setOnLongClickListener(longClickListener); 
    tapeLine.setOnClickListener(remainClickListener); 
    return tapeLine; 
} 

목록보기의 이상한 행동의 배경은 무엇인가 : 여기서 중요한 코드? 나는 안드로이드 소스에서 약간의 디버깅과 연구를했다. 안드로이드가 뷰를 업데이트 할 때 onMeasure와 onLayout이라는 두 가지 중요한 단계가 있습니다. ListAdapter의 getView 메소드는 뷰를 그리기 위해 호출 될뿐만 아니라 onMeasure 중에도 호출됩니다. 나중에이 경우보기가 생성되지만 아직 이벤트를 처리하기 위해 이벤트 체인에 등록되지 않았습니다.

onMeasure 용으로 만든보기를 나중에 다시 화면에 그려야 할 때는 Android 시스템에서 등록해야 클릭 이벤트를 처리 할 수 ​​있습니다. 이 특별한 경우 Android develepers는 더러운 해킹으로 간주 될 수있는 무언가를했습니다. LayoutParams의 특별한 플래그는 이벤트 변경에 뷰를 등록해야하는지 결정하는 데 사용됩니다.

내 문제 :보기를 다시 사용할 때 LayoutParams를 다시 설정하면이 플래그가 항상 재설정됩니다. 따라서 안드로이드 시스템은 뷰를 등록하지 않고 이벤트가 전달되지 않습니다.

요약하면 : ListAdapter의 getView에서보기를 다시 사용하면 안드로이드 시스템의 내부 정보를 유지하기 때문에 LayoutParams를 덮어 쓰지 않습니다.

+0

동일한 문제가있었습니다. 내 경우 레이아웃은 목록의 데이터 소스를 기반으로 크기를 조정해야하므로 처음으로 뷰가 부풀려지면서 layout.params가 변경되고 행 항목에 대한 클릭이 다시 제대로 작동했습니다. –

+0

OM * G, 안돼, 그게 내 것이 었어! 그게 바로 뒤로, 애매하고 완전히 뇌사 상태입니다. API는 계약이며이 계약은 준수되지 않습니다. 이 시간을 잃어 버렸습니다. Google 개발자가 내 근처에 있도록 두지 마십시오. 이 일에 열중하게 해줘서 고맙다. –

1

이 방법으로 누구에게 도움이되는지 확신 할 수 없지만 대신 TableLayout과 비슷한 문제가 있습니다. 위의 해결 방법으로 내 문제가 해결되지 않았습니다.

는 나에게 문제가 있었다 : android:animateLayoutChanges="true"

이 제대로 작동하려면 내 TableLayout을 행 내 내 버튼 클릭을 허용십시오. 위의 속성에 의존하는 대신 수동으로 내보기에 애니메이션을 적용해야했습니다.

+0

비활성화 애니메이션도 저에게 효과적이었습니다. –

관련 문제