Android ListView Selection Center zoom in (use up and down key control, not touch screen)

Keywords: Android network xml encoding

Recently, there is a function machine project (not supporting touch screen) that needs to realize the effect of enlarging the selected items of ListView in the middle. On the network, most of them are the effect of sliding the screen by hand, and only one can be written by themselves.
The effect is achieved, but there are still small problems. The implementation principle is mainly
1 call the setSelection method to make the item item up or down
2 call setSelectionFromTop to make the selected item in the middle of the screen
There are several problems:
1 the first few items cannot be centered (you can use the solution of filling in blank items)
2 when you press the up and down keys to move the item, you will see that listview slightly shakes (because setSelection will move the selected item to the top of the visible part of listview, and then setSelectionFromTop will move the item down again. There is no way to solve this problem for the moment. Please give me more advice if you can solve it)
demo below
1.item layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

2. Page layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="${relativePackage}.${activityClass}" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

</LinearLayout>

3.Adapter

/**
 * Created by caihuijian on 18-2-7.
 */

public class ReportSpinnerAdapter extends BaseAdapter {

    private static String TAG = "ReportSpinnerAdapter";
    private Context context;
    private List<String> str;

    private ListView list;
    public static int select_item = -1;

    //Hide cardinality of entries and offsets
    private int n = 1;

    public ReportSpinnerAdapter(Context context, List<String> str, ListView list) {
        this.context = context;
        this.str = str;
        this.list = list;
    }

    @Override
    public int getCount() {
        return str.size();
    }

    @Override
    public Object getItem(int position) {
        return str.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder hold;
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item,
                    parent, false);
            hold = new ViewHolder();
            hold.textView = (TextView) convertView.findViewById(R.id.text);
            convertView.setTag(hold);
        } else {
            hold = (ViewHolder) convertView.getTag();
        }
        hold.textView.setText(str.get(position));

        Log.v(TAG, "MainActivity.select_item " + MainActivity.select_item
                + " position " + position);
        // Selected item zoom in
        if (MainActivity.select_item == position) {
            hold.textView.setTextSize(17); // Selected Item font size 33
            hold.textView.setAlpha(0.9f);
        } else {
            // Unchecked items reduce transparency
            hold.textView.setTextSize(15); // Unselected Item font size 30
            hold.textView.setAlpha(0.5f);
        }

        if (n <= 1) {
            n = getVisibleCount() / 2;
        }
        if (position <= n || (position >= (str.size() - n - 1))) {
            // Need to hide the first and last (visibleCount+1/2) entries
            Log.v(TAG, "position " + position + " str.size() " + str.size()
                    + " n " + n);
            hold.textView.setAlpha(0.0f);
        }
        return convertView;
    }

    static class ViewHolder {
        TextView textView;
    }

    public int getN() {
        return n;
    }

    public int getVisibleCount() {
        int tempCount = (list.getLastVisiblePosition())
                - list.getFirstVisiblePosition();
        return tempCount;
    }
}

4. main interface

public class MainActivity extends ListActivity {

    private static String TAG = "MainActivity";
    ReportSpinnerAdapter adapter;
    ListView listView;
    public static int select_item = 1;

    // TODO int n//n is the number not displayed

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Analog data initialization
        List<String> datas = new ArrayList<String>();
        for (int i = 0; i < 20; i++) {
            datas.add("test " + i);
        }
        adapter = new ReportSpinnerAdapter(this, datas, getListView());
        listView = getListView();
        listView.setAdapter(adapter);
        listView.setOnItemSelectedListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> arg0, View arg1,
                    int arg2, long arg3) {
                Log.v(TAG, "onItemSelected");
                // Store the selected item location in the adapter
                select_item = arg2;
                // Move the selected item to the middle of the screen
                getListView().smoothScrollToPositionFromTop(select_item,
                        (int) getCenterY(), 1);
                adapter.notifyDataSetChanged();
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
            }
        });
    }

    @Override
    protected void onResume() {
        // Initialize the default selection item 2 in the middle of the screen
        getListView().setSelectionFromTop(3, (int) getCenterY());
        super.onResume();
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        final int keyCode = event.getKeyCode();
        final int action = event.getAction();
        int adapterCount = adapter.getCount();

        // Mask continuous press events and only listen for up events
        if (action != KeyEvent.ACTION_UP && keyCode != KeyEvent.KEYCODE_BACK) {
            return false;
        } else {
            switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_DOWN:
                Log.v(TAG, "down break select_item" + select_item
                        + " adapterCount " + adapterCount);
                // Move to the last n to mask the keycode dpad down event
                if (select_item == adapterCount - adapter.getN() - 2) {
                    return false;
                }
                // Move to next
                getListView().setSelection(select_item + 1);
                break;
            case KeyEvent.KEYCODE_DPAD_UP:
                Log.v(TAG, "up break select_item" + select_item);
                // Move to n to mask keycode dpad up event
                if (select_item == adapter.getN() + 1) {
                    return false;
                }
                // Move to previous
                getListView().setSelection(select_item - 1);
                break;
            case KeyEvent.KEYCODE_DPAD_CENTER:
                return true;
            default:
                return super.dispatchKeyEvent(event);
            }
        }

        return super.dispatchKeyEvent(event);
    }

    private double getCenterY() {
        // Calculated row height
        View listItem = adapter.getView(0, null, listView);
        listItem.measure(0, 0);
        int height = listItem.getMeasuredHeight() + listView.getDividerHeight();

        // Calculate display entries
        // Calculate offset
        return (adapter.getN() * height);
    }
}

Posted by kristinac on Fri, 03 Apr 2020 03:25:49 -0700