I'm using vertical RecyclerView
to list my items and SnapHelper
to snap center item. The idea is to randomize selection, so user swipe screen or shake the device and it is scrolling to random position.
Number of items is 20, however I use Integer.MAX_VALUE
for the number of elements in RecyclerView
and initialize RecyclerView with position Integer.MAX_VALUE / 2
to create some kind of endless list.
To scroll to random position on device shake I need to know current snapped item position.
Is there any way to do it?
Here is my Fragment code:
public class PlaceListFragment extends Fragment {
private static final String TAG = "PlaceListFragment";
public static final String ARG_KEY1 = "key1";
private ArrayList<PlaceItem> places;
private RecyclerView recyclerView;
private SensorManager sensorManager;
private float accelValue;
private float accelLast;
private float shake;
SnapHelper snapHelper;
Vibrator vibe;
public static PlaceListFragment newInstance() {
Bundle args = new Bundle();
PlaceListFragment fragment = new PlaceListFragment();
fragment.setArguments(args);
return fragment;
}
public static PlaceListFragment newInstance(ArrayList<PlaceItem> places) {
Bundle args = new Bundle();
args.putParcelableArrayList(PlaceListActivity.KEY_PLACES, places);
PlaceListFragment fragment = new PlaceListFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate()");
super.onCreate(savedInstanceState);
places = getArguments().getParcelableArrayList(PlaceListActivity.KEY_PLACES);
accelValue = SensorManager.GRAVITY_EARTH;
accelLast = SensorManager.GRAVITY_EARTH;
shake = 0.00f;
vibe = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_place_list, container, false);
recyclerView = (RecyclerView) v.findViewById(R.id.place_list);
snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
recyclerView.setOnFlingListener(snapHelper);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(new PlaceListAdapter(getActivity(), places));
recyclerView.scrollToPosition(PlaceListAdapter.MIDDLE);
sensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);
sensorManager.registerListener(sensorListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);
return v;
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
private final SensorEventListener sensorListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
accelLast = accelValue;
accelValue = (float) Math.sqrt((double) (x*x + y*y + z*z));
float delta = accelValue - accelLast;
shake = shake * 0.9f + delta;
if (shake > 12) {
vibe.vibrate(200);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
}
And here is adapter:
public class PlaceListAdapter extends RecyclerView.Adapter<PlaceListAdapter.PlaceAdapterHolder> {
private final FragmentActivity context;
public static final int HALF_MAX_VALUE = Integer.MAX_VALUE/2;
public static int MIDDLE;
private List<PlaceItem> placeItems;
public static class PlaceAdapterHolder extends RecyclerView.ViewHolder {
private ImageView image;
private TextView textMain;
private TextView textRating;
public PlaceAdapterHolder(View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.icon);
textMain = (TextView) itemView.findViewById(R.id.txt_main_line);
textRating = (TextView) itemView.findViewById(R.id.txt_right_field);
}
public void bindPlace(PlaceItem placeItem) {
String placeName = placeItem.getName() == null? "?":placeItem.getName();
String firstLetter = placeName.substring(0, 1);
ColorGenerator generator = ColorGenerator.MATERIAL; // or use DEFAULT
int color = generator.getColor(placeName);
TextDrawable drawable = TextDrawable.builder()
.beginConfig()
.toUpperCase()
.endConfig()
.buildRect(firstLetter, color);
image.setImageDrawable(drawable);
textMain.setText(placeItem.getName());
textRating.setText(placeItem.getRating());
}
}
public PlaceListAdapter(FragmentActivity context, List<PlaceItem> placeItems) {
this.context = context;
this.placeItems = placeItems;
MIDDLE = HALF_MAX_VALUE - HALF_MAX_VALUE % placeItems.size();
}
@Override
public PlaceListAdapter.PlaceAdapterHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.place_list_one_line_item, parent, false);
return new PlaceAdapterHolder(view);
}
@Override
public int getItemCount() {
return Integer.MAX_VALUE;
}
@Override
public void onBindViewHolder(PlaceListAdapter.PlaceAdapterHolder holder, final int position) {
final PlaceItem placeItem = getItem(position);
holder.bindPlace(placeItem);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentManager fm = context.getSupportFragmentManager();
PlaceDetailsFragment dialog = PlaceDetailsFragment.newInstance(getItem(position));
dialog.show(fm, "DETAILS_DIALOG");
}
});
}
private PlaceItem getItem(int position)
{
return placeItems.get(position % placeItems.size());
}
}
linearLayoutManager.findFirstCompletelyVisibleItemPosition();
,linearLayoutManager.findLastCompletelyVisibleItemPosition();
and then find a middle of it – Canon