2013-04-28 3 views
0

ListView을 가져 와서 행이 끝에 가까울지라도 정상적인 안드로이드에서 해당 높이를 스크롤 할 수 없더라도 특정 행을 해당 Listview's 경계의 위쪽으로 스크롤 할 수있게하려고합니다. ListView (특정 트윗을 조사 할 때 트위터가 작동하는 방식과 유사하며 그 아래에 아무 것도없는 경우에도 항상 트윗이 맨 위로 스크롤 가능)특정 행을 항상 맨 위로 스크롤 할 수있는 ListView?

이 작업을 쉽게 수행 할 수있는 방법이 있습니까? 나는 맨 위로 스크롤하고 원하는 공간을 차지하기 위해 하단 패딩을 적용하고자하는 행을 측정 해 보았습니다. 그러나 그것은 이상한 결과를 낳습니다. (패딩 변경과 뷰의 측정 패스 도중 잘못된 것이기 때문에 나는 예상합니다. 권고). 문제의 셀 (및 그 이후의 모든 셀)의 측정 된 높이가 아직 발생하지 않았으므로 측정 값 통과 전에 작동하지 않습니다.

+0

목록의 마지막 요소를 스크롤하여 화면 아래에 빈 공간이 있는지를 의미합니까? – Gustek

+0

그래, 그게 내가해야 할 일이다. – Kevlar

+0

꽤 해킹 된 것이지만 ... 빈 끝에 [footer] (http://developer.android.com/reference/android/widget/ListView.html#addFooterView%28android.view.View.29)를 추가하십시오. 화면 크기의 목록? –

답변

-2

나는 알아 냈다. 조금 복잡하지만 대부분 작동하는 것 같습니다 :

public int usedHeightForAndAfterDesiredRow() { 
    int totalHeight = 0; 
    for (int index = 0; index < rowHeights.size(); index++) { 
     int height = rowHeights.get(rowHeights.keyAt(index)); 
     totalHeight += height; 
    } 
    return totalHeight; 
} 

@Override 
public View getView(int position, View convertView, final ViewGroup parent) { 
    View view = super.getView(position, convertView, parent); 

    if (measuringLayout.getLayoutParams() == null) { 
     measuringLayout.setLayoutParams(new AbsListView.LayoutParams(parent.getWidth(), parent.getHeight())); 
    } 

    // measure the row ahead of time so that we know how much space will need to be added at the end 
    if (position >= mainRowPosition && position < getCount()-1 && rowHeights.indexOfKey(position) < 0) { 
     measuringLayout.addView(view, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); 
     measuringLayout.measure(MeasureSpec.makeMeasureSpec(parent.getWidth(), MeasureSpec.EXACTLY), MeasureSpec.UNSPECIFIED); 

     rowHeights.put(position, view.getMeasuredHeight()); 
     measuringLayout.removeAllViews(); 

     view.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); 
    } 

    if (position == getCount()-1 && view.getLayoutParams().height == 0) { 
     // we know how much height the prior rows take, so calculate the last row with that. 
     int height = usedHeightForAndAfterDesiredRow(); 
     height = Math.max(0, parent.getHeight() - height); 
     view.getLayoutParams().height = height; 
    } 
    return view; 
} 

이것은 내 어댑터에 들어 있습니다. 그것은 병합 어댑터의 하위 클래스이지만 코드에 넣고 행을 생성하는 대신 수퍼 호출을 대신 사용할 수 있습니다.

getView()의 첫 번째 if 문은 측정만을위한 프레임 레이아웃 멤버 var의 레이아웃 매개 변수를 설정하며 상위 뷰는 없습니다.

두 번째 if 문은 맨 위로 스크롤하는 데 신경 쓰는 행의 위치를 ​​포함하여 행의 모든 ​​행 높이를 계산합니다. rowHeights는 SparseIntArray입니다.

마지막 if 문은 레이아웃 매개 변수가있는보기가 추가로 하나만있는 것으로 가정합니다.보기의 맨 아래에 이미 투명하고 확장되도록 의도 된 레이아웃 매개 변수가 이미 설정되어 있습니다. usedHeightForAndAfterDesiredRow 호출은 상위 뷰의 높이에서 빼는 모든 미리 계산 된 높이를 더합니다 (최소 높이가 0이되므로 음수 높이를 얻지 못합니다). 이렇게하면 다른 항목의 높이에 따라 임의로 펼쳐지는 아래쪽에보기가 작성되므로 목록의 위치에 관계없이 특정 행이 항상 목록의 맨 위로 스크롤 할 수 있습니다.

+0

의'position> = mainRowPosition''mainRowPosition'은 무엇이되어야 하는가? – Abhishek

+0

측정 값은 무엇입니까? – Prakash

+0

당신의 솔루션은 당신을 위해 일할 수도 있지만 중요한 정보가 다른 사람들에게 유용하지 않게됩니다. Abhishek과 Prakash가 이미 주석을 달았으니, Llayout과 mainRowPosition은 무엇을 측정합니까? –

2

여러분은 setSelectionFromTop listview 방법과 같습니다.

mListView.setSelectionFromTop(listItemIndex, 0); 
+0

나는 이미 그걸 사용하고 있는데, 행이 정상적으로 스크롤 될 수 있도록 원하는 행 아래에 충분한 셀이 있으면 작동하지만, 사용자가 할 수없는 경우 행의 맨 위에 강제로 표시하지는 않습니다 내가 필요로하는 것이 아니기 때문에 스스로 스크롤하십시오. – Kevlar

관련 문제