your programing

Android ListView 새로 고침 단일 행

lovepro 2020. 10. 16. 07:53
반응형

Android ListView 새로 고침 단일 행


의 단일 행에 대한 데이터를 얻은 후 ListView해당 단일 행을 업데이트하고 싶습니다.

현재 사용하고 notifyDataSetChanged();있지만 View반응이 매우 느립니다. 다른 해결책이 있습니까?


한 가지 옵션은 ListView직접 조작하는 것 입니다. 먼저 체크 사이에 업데이트 된 행의 인덱스 인 경우 getFirstVisiblePosition()getLastVisiblePosition(),이 두 당신에게 화면에 표시되는 어댑터의 첫 번째와 마지막 위치를 제공합니다. 그런 다음 행 View가져 와서 getChildAt(int index)변경할 수 있습니다.


Romain Guy Google I / O 세션 에서 얼마 전에 설명했듯이 목록보기에서 하나의보기 만 업데이트하는 가장 효율적인 방법은 다음과 같습니다 (이는 전체보기 데이터를 업데이트 함).

ListView list = getListView();
int start = list.getFirstVisiblePosition();
for(int i=start, j=list.getLastVisiblePosition();i<=j;i++)
    if(target==list.getItemAtPosition(i)){
        View view = list.getChildAt(i-start);
        list.getAdapter().getView(i, view, list);
        break;
    }

target어댑터의 한 항목 이라고 가정 합니다.

이 코드는를 검색 한 ListView다음 현재 표시된보기를 찾아보고, target찾고 있는 항목을 표시된 각보기 항목과 비교하고 , 대상이 이러한 항목 중 하나 인 경우 주변보기를 가져 와서 해당보기에서 어댑터 getView실행 하여 디스플레이를 새로 고칩니다.

사이드 노트 invalidate는 일부 사람들이 기대하는 것처럼 작동하지 않고 getView처럼 뷰를 새로 고치지 않으므로 notifyDataSetChanged전체 목록을 다시 작성하고 getview표시되는 모든 항목을 호출 invalidateViews하고 여러 번에 영향을 미칩니다.

마지막으로 행보기의 하위 항목 만 변경해야하고 전체 행을 변경해야하는 경우에도 추가 성능을 얻을 수 있습니다 getView. 이 경우 다음 코드로 대체 할 수 있습니다 list.getAdapter().getView(i, view, list);( TextView텍스트 변경 예제 ).

((TextView)view.findViewById(R.id.myid)).setText("some new text");

코드에서 우리는 신뢰합니다.


이 더 간단한 방법은 저에게 잘 작동하며 뷰를 확보하려면 위치 인덱스 만 알면됩니다.

// mListView is an instance variable

private void updateItemAtPosition(int position) {
    int visiblePosition = mListView.getFirstVisiblePosition();
    View view = mListView.getChildAt(position - visiblePosition);
    mListView.getAdapter().getView(position, view, mListView);
}

다음 코드가 저에게 효과적이었습니다. GetChild ()를 호출 할 때 목록의 첫 번째 항목과 관련이 있으므로 오프셋해야합니다.

int iFirst = getFirstVisiblePosition();
int iLast = getLastVisiblePosition();

if ( indexToChange >= numberOfRowsInSection() ) {
    Log.i( "MyApp", "Invalid index. Row Count = " + numberOfRowsInSection() );
}
else {      
    if ( ( index >= iFirst ) && ( index <= iLast ) ) {
        // get the view at the position being updated - need to adjust index based on first in the list
        View vw = getChildAt( sysvar_index - iFirst );
        if ( null != vw ) {
            // get the text view for the view
            TextView tv = (TextView) vw.findViewById(com.android.myapp.R.id.scrollingListRowTextView );
            if ( tv != null ) {
                // update the text, invalidation seems to be automatic
                tv.setText( "Item = " + myAppGetItem( index ) + ". Index = " + index + ". First = " + iFirst + ". Last = " + iLast );
            }
        }
    }
}  

사용 사례에 맞다면 훨씬 더 효율적인 방법이 있습니다.

상태를 변경하고 어떻게 든 적절한 (위치를 아는 것으로) 부를 수 mListView.getAdapter().getView()있다면 가장 효율적일 것입니다.

I can demonstrate a really easy way to do it, by creating an anonymous inner class in my ListAdapter.getView() class. In this example I have a TextView showing a text "new" and that view is set to GONE when the list item is clicked:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // assign the view we are converting to a local variable
    View view = convertView;

    Object quotation = getItem(position);
    // first check to see if the view is null. if so, we have to inflate it.
    if (view == null)
        view = mInflater.inflate(R.layout.list_item_quotation, parent, false);

    final TextView newTextView = (TextView) view.findViewById(R.id.newTextView);

    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mCallbacks != null)
                mCallbacks.onItemSelected(quotation.id);
            if (!quotation.isRead()) {
                servicesSingleton.setQuotationStatusReadRequest(quotation.id);
                quotation.setStatusRead();
                newTextView.setVisibility(View.GONE);
            }
        }
    });

    if(quotation.isRead())
        newTextView.setVisibility(View.GONE);
    else
        newTextView.setVisibility(View.VISIBLE);

    return view;
}

The framework automatically uses the correct position and you do have to worry about fetching it again before calling getView.


Just for the record, did anyone consider the 'View view' on the override method ?

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

                    //Update the selected item
                    ((TextView)view.findViewById(R.id.cardText2)).setText("done!");

                }

참고URL : https://stackoverflow.com/questions/2123083/android-listview-refresh-single-row

반응형