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);
}
}