2011-12-24 4 views
0

사용자 정의 ListView 클래스 (ListView에서 서브 클래 싱 됨)가 있으며, 마지막 뷰 요소의 아래쪽에 작은 패딩을 추가하여 필자가 가지고있는 작은 막대로 겹치지 않도록해야합니다 화면 하단. 자식 뷰가 listview의 보이는 영역을 지나면 자만하면됩니다. 나는 이것을 달성하기 위해이 코드를 사용하는 것을 시도하고있다 :ListView getFirstVisiblePosition getFirstVisiblePosition getCount 값

@Override 
protected void onLayout (boolean changed, int left, int top, int right, int bottom) { 
    super.onLayout(changed, left, top, right, bottom); 

    // If there are hidden listview items we need to add a small padding to the last one so that it 
    // partially hidden by the bottom sliding drawer handle 
    if (this.getLastVisiblePosition() - this.getFirstVisiblePosition() + 1 > this.getCount()) { 
     LinearLayout v2 = (LinearLayout) this.getChildAt(this.getCount() - 1); 
     v2.setPadding(v2.getPaddingLeft(), v2.getPaddingTop(), v2.getPaddingRight(), 
       v2.getPaddingBottom() + 5); 
    } 
} 

그러나 getLastVisiblePostion(), getFirstVisiblePostion()과 getCount()에 의해 반환되는 값은 어댑터가 아직 보유하고 무엇을 반영하지 않습니다. 어댑터가 아직 데이터의 ListView를 알리지 않았기 때문에 이것을 가정하고 있지만 ListView가 데이터에 대해 실제로 알고 정확한 값을 가지고 있는지를 파악할 수 없습니다. 이 코드는 활동이로드 될 때 실행 중입니다.

렌더링 프로세스의 어느 시점에서이 데이터에 액세스 할 수 있습니까? 또한 AsyncTask를 사용하여 데이터베이스의 데이터를로드 한 다음 어댑터를 작성하여 목록보기에 추가한다고도합니다. ListView 내에서 사용할 수있는 이벤트가 있는데 어댑터가 데이터를 추가하면/listview가 새 항목을 렌더링 할 때 발생합니다.

답변

0

가장 좋은 해결책인지 확실치 않지만 Android 용 풀 새로 고침 구현의 분기 중 하나에서 목록의 높이가 모든 목록의 전체 높이와 비교됩니다. 항목. 당신이 말하고있는 것에서는 여분의 패딩을 적용 할 것인지 아닌지를 결정하기 위해 찾고있는 정보와 같다고 들립니다.

구현의 관련 부분은 다음과 같은 세 가지 방법에 있습니다

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    if (mHeight == -1) { // do it only once 
     mHeight = getHeight(); // getHeight only returns useful data after first onDraw() 
     adaptFooterHeight(); 
    } 
} 

/** 
* Adapts the height of the footer view. 
*/ 
private void adaptFooterHeight() { 
    int itemHeight = getTotalItemHeight(); 
    int footerAndHeaderSize = mFooterView.getHeight() 
     + (mRefreshViewHeight - mRefreshOriginalTopPadding); 
    int actualItemsSize = itemHeight - footerAndHeaderSize; 
    if (mHeight < actualItemsSize) { 
     mFooterView.setHeight(0); 
    } else { 
     int h = mHeight - actualItemsSize; 
     mFooterView.setHeight(h); 
     setSelection(1); 
    } 
} 

/** 
* Calculates the combined height of all items in the adapter. 
* 
* Modified from http://iserveandroid.blogspot.com/2011/06/how-to-calculate-lsitviews-total.html 
* 
* @return 
*/ 
private int getTotalItemHeight() { 
    ListAdapter adapter = getAdapter(); 
    int listviewElementsheight = 0; 
    for(int i =0; i < adapter.getCount(); i++) { 
     View mView = adapter.getView(i, null, this); 
     mView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 
       MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 
     listviewElementsheight+= mView.getMeasuredHeight(); 
    } 
    return listviewElementsheight; 
} 

전체 소스 코드

는 GitHub의에 here를 찾을 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. 그래도 여전히 같은 문제가 있습니다. 문제는 onLayout이 호출되었을 때 어댑터가 아직 항목에 대한 정보를 제공하지 않았다는 것입니다. 이 데이터가 추가 될 때까지 연결할 수 있습니까? –

+0

ListView에서 어댑터를 설정할 때'mHeight'를'-1'로 다시 설정해 보셨습니까? 그것이 들리는 것으로부터 처음으로 그려진 후에리스트 방법을 채우고 있습니다. 즉, 계산 된 높이가 아마도 '0'이고 실제로 데이터를 설정하는 순간 정확하지 않다는 것을 의미합니다. 따라서 업데이트해야합니다. 내가 아는 한, 사용할 수있는 특별한 이벤트가 없습니다. 그렇다면 위 코드의 해결 방법은 필요하지 않습니다. –

0

보다 큰 숫자의 getFirstVisiblePosition()이 반환 될 때 비슷한 문제가 발생했습니다.
listView.setAdapter(listView.getAdapter())로 전화하여 문제를 해결했습니다.

관련 문제