UFO ET IT

Android ListView setSelection ()이 작동하지 않는 것 같습니다.

ufoet 2020. 11. 15. 12:09
반응형

Android ListView setSelection ()이 작동하지 않는 것 같습니다.


나는이 ListActivity것을 구현 onListItemClick()하고 된 전화 doSomething()클래스의 기능을. 후자 객체 l.setSelection(position)어디에 있는지 포함 합니다.lListView

이제 onClickListener()몇 가지 작업을 수행하는 버튼 클릭을 수신하고 doSomething().

첫 번째 경우 선택한 항목이 적절하게 배치되지만 후자에서는 아무 일도 일어나지 않습니다.

이 이상한 행동에 대한 단서가 있고 어떻게 작동하게 만들 수 있습니까?


아마도 기능을 사용해야 할 수도 있습니다.

ListView.setItemChecked(int position, boolean checked);

메서드 requestFocusFromTouch()를 호출하기 전에 사용setSelection()


나는 이것이 오래된 질문이라는 것을 알고 있지만 이런 식으로 해결 한 비슷한 문제가 있습니다.

mListView.clearFocus();
mListView.post(new Runnable() {
    @Override
    public void run() {
        mListView.setSelection(index);
    }
});

당신은 포장해야 할 수도 있습니다 setSelection()A의 postED Runnable( 참조 ).


setSelection()시각적 인 영향을 미치지는 않습니다. 선택 표시 줄은 D 패드 / 트랙볼을 사용하여 목록을 탐색하는 경우에만 나타납니다. 화면을 탭하여 무언가를 클릭하면 선택 표시 줄이 잠깐 나타나고 사라집니다.

따라서 setSelection()활동이 터치 모드가 아닌 경우에만 시각적 인 영향을 미칩니다 (즉, 사용자가 마지막으로 한 작업은 D 패드 / 트랙볼을 사용하는 것입니다).

나는 이것이 당신이 제공 한 설명을 고려할 때 이것이 당신의 현상을 설명한다고 100 % 확신하지 못하지만, 한 번의 가치가 있다고 생각했습니다 ...


ListView에 어댑터를 사용하는 경우 다음 코드를 어댑터에 추가하십시오.

public class MyAdapter extends
        ArrayAdapter<MyClass> {


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater inflator = (LayoutInflater) getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            rowView = inflator.inflate(R.layout.my_adapter, null);
        } else {
            rowView = (View) convertView;
        }

        //...

        // set selected item
        LinearLayout ActiveItem = (LinearLayout) rowView;
        if (position == selectedItem)
        {
            ActiveItem
                    .setBackgroundResource(R.drawable.background_dark_blue);

            // for focus on it
            int top = (ActiveItem == null) ? 0 : ActiveItem.getTop();
            ((ListView) parent).setSelectionFromTop(position, top);
        }
        else
        {
            ActiveItem
                    .setBackgroundResource(R.drawable.border02);
        }

    }

    private int selectedItem;

    public void setSelectedItem(int position) {
        selectedItem = position;
    }

}

활동에서 :

myAdapter.setSelectedItem(1);

Webcontent에 매우 큰 요청이 있습니다. onCreateView에서 코드를 사용했을 때 Listview가로드를 완료하지도 못했습니다. 내 AsyncTask의 onPostExecute에 넣었습니다.

            //Get last position in listview
        if (listView != null && scrollPosition != 0) {
            listView.clearFocus();
            listView.requestFocusFromTouch();
            listView.post(new Runnable() {
                @Override
                public void run() {
                    listView.setItemChecked(scrollPosition, true);
                    listView.setSelection(scrollPosition);
                }
            });
        }

클릭시 체크 인 항목을 설정하는 것을 잊지 마십시오;)


나를 위해 전화

listView.notifyDataSetChanged();
listView.requestFocusFromTouch();

그리고

 listView.setSelection(position);

문제를 해결했습니다.

if you do that in a runnable it works without calling requestFocusFromTouch(), but the old position of the ListView is showen for a sekound.


Maybe you should use the smoothScrollToPosition(int position) method of ListView


In my case smoothScrollToPosition(int position) worked, can you also tell me how to set that scrolled position into center of the list. It appeared at the bottom of visible items.


For me it helped to set
ListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); or ListView.CHOICE_MODE_MULTIPLE
then
ListView.setSelection(position) or ListView.setItemChecked(position, true);
works fine


Found a solution in my case. I am not using a Runnable since my class is extending ListFragment. What I had to do is make my index a final; final index = 5; mListView.setSelection(index);


I found that sometimes setSelection will not work because I set attribute "android:height" of listView to "wrap_content".

And the times my App won't work is that when listView become scrollable from non-scrollable.

For example, if my app is "File Browser App". When my list is less than, let's say 6, then it's non-scrollable. Now I return to the parent directory, and it has 11 objects, and I want to set selection to some position, and it won't work here.

to\from    |    Scrollable  | non-Scrollable

Scrollable | O | O( of course )

non-Scrollable | X | O( of course )

I don't want to use post(Runnable), because there will has delay.

==================================

Answer:

You can try to set "android:height" to "match_parent"

God, it spends three days.


When use post to setSelection(), the ListView will see first , then scroll to the position , thank to "魏經軒", then layout actually will effect the setSelection(), because setSelection() call the setSelectionFromTop(int position, int y), there is another way to solve it.

listView.setAdapter(listView.getAdapter());
listView.setSelection(123);

Simply try this code

  listView.setAdapter(adapter);
  listView.setSelection(position);
  adapter.notifyDataSetChanged(); 

You can try 2 ways like these:
Solution A:

    mListView.post(new Runnable() {
        @Override
        public void run() {
            if (null != mListView) {
                mListView.clearFocus();
                mListView.requestFocusFromTouch();
                mListView.setSelection(0);
            }
        }
    });

In some complicated situation, this solution will bring some new problems in Android 8.x.
Besides it may cause unexpected onFocusChange().

Solution B: Define a custom view extends ListView. Override method handleDataChanged().Then setSelection(0). In CustomListView:

@Override
protected void handleDataChanged() {
    super.handleDataChanged();
    if (null != mHandleDataChangedListener){
        mHandleDataChangedListener.onChanged();
    }
}
HandleDataChangedListener mHandleDataChangedListener;

public void setHandleDataChangedListener(HandleDataChangedListener handleDataChangedListener) {
    this.mHandleDataChangedListener = handleDataChangedListener;
}

public interface HandleDataChangedListener{
    void onChanged();
}

In activity:

    mListView.setHandleDataChangedListener(new CustomListView.HandleDataChangedListener() {
        @Override
        public void onChanged() {
            mListView.setHandleDataChangedListener(null);
            mListView.setSelection(0);
        }
    });
    mAdapter.notifyDataSetChanged();

Ok, That's it.


For me the solution to this problem was:

listView.clearChoices();

참고URL : https://stackoverflow.com/questions/1446373/android-listview-setselection-does-not-seem-to-work

반응형