Skip to content

Commit

Permalink
Added SectionIndicator for viewing section while fast scrolling
Browse files Browse the repository at this point in the history
  • Loading branch information
danoz73 committed Feb 18, 2015
1 parent 8b47f10 commit b3e2d2f
Show file tree
Hide file tree
Showing 30 changed files with 871 additions and 186 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@
import android.view.MenuItem;

import com.example.android.recyclerview.R;
import com.example.recyclerviewfastscroller.fragment.RecyclerViewFragment;
import com.example.recyclerviewfastscroller.fragment.RecyclerViewWithSectionsFragment;
import com.example.recyclerviewfastscroller.fragment.RecyclerViewWithFastScrollerFragment;
import com.example.recyclerviewfastscroller.fragment.RecyclerViewWithSectionIndicatorFragment;
import com.example.recyclerviewfastscroller.ui.scroller.sectionindicator.title.SectionTitleIndicator;
import com.example.recyclerviewfastscroller.ui.scroller.vertical.VerticalRecyclerViewFastScroller;

/**
* Simple activity for displaying the {@link RecyclerViewFragment}
* Simple activity for displaying an example of the {@link VerticalRecyclerViewFastScroller} as well as
* {@link SectionTitleIndicator} usage paired with the fast scroller
*/
public class MainActivity extends FragmentActivity {

Expand All @@ -39,7 +42,7 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);

if (savedInstanceState == null) {
RecyclerViewFragment fragment = new RecyclerViewFragment();
RecyclerViewWithFastScrollerFragment fragment = new RecyclerViewWithFastScrollerFragment();
replaceCurrentFragment(fragment);
}
}
Expand All @@ -61,11 +64,16 @@ public boolean onCreateOptionsMenu(Menu menu) {
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.menu_item_list_no_section_indicator:
RecyclerViewWithFastScrollerFragment simpleFastScrollerFragment = new RecyclerViewWithFastScrollerFragment();
replaceCurrentFragment(simpleFastScrollerFragment);
return true;
case R.id.menu_item_list_with_sections:
RecyclerViewWithSectionsFragment sectionsFragment = new RecyclerViewWithSectionsFragment();
RecyclerViewWithSectionIndicatorFragment sectionsFragment = new RecyclerViewWithSectionIndicatorFragment();
replaceCurrentFragment(sectionsFragment);
return true;
default:
return super.onOptionsItemSelected(item);
}
}}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.example.recyclerviewfastscroller.data;

import android.support.annotation.NonNull;

/**
* Data object representing a color
*/
public class ColorData {

private final int mColorInt;
private final ColorGroup mColorGroup;

public ColorData(int colorInt, @NonNull ColorGroup colorGroup) {
mColorInt = colorInt;
mColorGroup = colorGroup;
}

public int getIntValue() {
return mColorInt;
}

public ColorGroup getColorGroup() {
return mColorGroup;
}

@Override
public String toString() {
return String.format("#%06X", (0xFFFFFF & mColorInt));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.example.recyclerviewfastscroller.data;

import android.graphics.Color;

/**
* Dummy dataset of N {@link ColorData} objects
*/
public class ColorDataSet {

private static final int DATA_SET_SIZE = 100;
private static final float NUM_HUES = 359;
private static final ColorData[] mColors = new ColorData[DATA_SET_SIZE];

public ColorDataSet() {
this(new ColorGroupCalculator());
}

private ColorDataSet(ColorGroupCalculator colorGroupCalculator) {
for (int i = 0; i < mColors.length; i++) {
mColors[i] = generateNewColor(i, mColors.length, colorGroupCalculator);
}
}

private ColorData generateNewColor(int position, int numColors, ColorGroupCalculator colorGroupCalculator) {
float positionBasedHue = position * (NUM_HUES / numColors);
int color = Color.HSVToColor(new float[] {positionBasedHue, 1, 1});
return new ColorData(color, colorGroupCalculator.getColorGroup(positionBasedHue));
}

public int getSize() {
return mColors.length;
}

public ColorData get(int position) {
return mColors[position];
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.example.recyclerviewfastscroller.data;

import android.graphics.Color;

/**
* Coarse groupings of colors by hue
*/
public enum ColorGroup {
RED_UPPER (345, 360, "Red"),
PINK (300, RED_UPPER.mMinimumHue, "Pink"),
PURPLE (260, PINK.mMinimumHue, "Purple"),
BLUE (175, PURPLE.mMinimumHue, "Blue"),
GREEN (70, BLUE.mMinimumHue, "Green"),
YELLOW (50, GREEN.mMinimumHue, "Yellow"),
ORANGE (25, YELLOW.mMinimumHue, "Orange"),
RED_LOWER (0, ORANGE.mMinimumHue, "Red"),
;

private final int mMinimumHue, mMaximumHue;
private final int mIntegerRepresentation;
private final String mName;

ColorGroup(int minimumHue, int maximumHue, String groupName) {
mMinimumHue = minimumHue;
mMaximumHue = maximumHue;
mName = groupName;
mIntegerRepresentation = Color.HSVToColor(new float[] { (maximumHue + minimumHue) / 2, 1, 1});
}

public String getName() {
return mName;
}

public boolean containsHue(int hue) {
return (hue >= mMinimumHue && hue < mMaximumHue);
}

public int getAsColor() {
return mIntegerRepresentation;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.example.recyclerviewfastscroller.data;

import android.support.annotation.NonNull;

/**
* Allow for finding a color group based on a hue
*/
class ColorGroupCalculator {

@NonNull
public ColorGroup getColorGroup(float hue) {
for (ColorGroup group : ColorGroup.values()) {
if (group.containsHue((int) hue)) {
return group;
}
}

throw new NullPointerException("Could not classify hue into Color Group!");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,14 @@
import android.view.ViewGroup;

import com.example.android.recyclerview.R;
import com.example.recyclerviewfastscroller.data.ColorDataSet;
import com.example.recyclerviewfastscroller.recyclerview.ColorfulAdapter;
import com.example.recyclerviewfastscroller.ui.scroller.vertical.VerticalRecyclerViewFastScroller;

/**
* Adapted from sample code that demonstrates the use of {@link RecyclerView} with a {@link LinearLayoutManager}
*/
public class RecyclerViewFragment extends Fragment {

private static final String TAG = "RecyclerViewFragment";
private static final int DATASET_COUNT = 100;
public class RecyclerViewWithFastScrollerFragment extends Fragment {

@Override
public void onCreate(Bundle savedInstanceState) {
Expand All @@ -44,16 +42,16 @@ public void onCreate(Bundle savedInstanceState) {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.recycler_view_frag, container, false);
View rootView = inflater.inflate(R.layout.recycler_view_with_fast_scroller_fragment, container, false);

RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
VerticalRecyclerViewFastScroller fastScroller = (VerticalRecyclerViewFastScroller) rootView.findViewById(R.id.fast_scroller);
fastScroller.setRecyclerView(recyclerView);
recyclerView.setOnScrollListener(fastScroller.getOnScrollListener());

setRecyclerViewLayoutManager(recyclerView);

RecyclerView.Adapter adapter = new ColorfulAdapter(getDummyDataSet());
RecyclerView.Adapter adapter = new ColorfulAdapter(new ColorDataSet());
recyclerView.setAdapter(adapter);

return rootView;
Expand All @@ -77,14 +75,4 @@ public void setRecyclerViewLayoutManager(RecyclerView recyclerView) {
recyclerView.scrollToPosition(scrollPosition);
}

/**
* Generates Strings for RecyclerView's adapter. This data would usually come from somewhere...
*/
private String[] getDummyDataSet() {
String[] data = new String[DATASET_COUNT];
for (int i = 0; i < DATASET_COUNT; i++) {
data[i] = "This is element #" + i;
}
return data;
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,3 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.recyclerviewfastscroller.fragment;

import android.os.Bundle;
Expand All @@ -25,16 +9,15 @@
import android.view.ViewGroup;

import com.example.android.recyclerview.R;
import com.example.recyclerviewfastscroller.data.ColorDataSet;
import com.example.recyclerviewfastscroller.recyclerview.ColorfulAdapter;
import com.example.recyclerviewfastscroller.ui.scroller.sectionindicator.title.SectionTitleIndicator;
import com.example.recyclerviewfastscroller.ui.scroller.vertical.VerticalRecyclerViewFastScroller;

/**
* Adapted from sample code that demonstrates the use of {@link RecyclerView} with a {@link LinearLayoutManager}
*/
public class RecyclerViewWithSectionsFragment extends Fragment {

private static final String TAG = "RecyclerViewFragment";
private static final int DATASET_COUNT = 100;
public class RecyclerViewWithSectionIndicatorFragment extends Fragment {

@Override
public void onCreate(Bundle savedInstanceState) {
Expand All @@ -44,17 +27,23 @@ public void onCreate(Bundle savedInstanceState) {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.recycler_view_frag, container, false);
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.recycler_view_with_fast_scroller_section_title_indicator_fragment, container, false);

RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
RecyclerView.Adapter adapter = new ColorfulAdapter(new ColorDataSet());
recyclerView.setAdapter(adapter);

RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
VerticalRecyclerViewFastScroller fastScroller = (VerticalRecyclerViewFastScroller) rootView.findViewById(R.id.fast_scroller);
VerticalRecyclerViewFastScroller fastScroller =
(VerticalRecyclerViewFastScroller) rootView.findViewById(R.id.fast_scroller);
fastScroller.setRecyclerView(recyclerView);

recyclerView.setOnScrollListener(fastScroller.getOnScrollListener());

setRecyclerViewLayoutManager(recyclerView);
SectionTitleIndicator sectionTitleIndicator =
(SectionTitleIndicator) rootView.findViewById(R.id.fast_scroller_section_title_popup);
fastScroller.setSectionIndicator(sectionTitleIndicator);

RecyclerView.Adapter adapter = new ColorfulAdapter(getDummyDataSet());
recyclerView.setAdapter(adapter);
setRecyclerViewLayoutManager(recyclerView);

return rootView;
}
Expand All @@ -77,14 +66,4 @@ public void setRecyclerViewLayoutManager(RecyclerView recyclerView) {
recyclerView.scrollToPosition(scrollPosition);
}

/**
* Generates Strings for RecyclerView's adapter. This data would usually come from somewhere...
*/
private String[] getDummyDataSet() {
String[] data = new String[DATASET_COUNT];
for (int i = 0; i < DATASET_COUNT; i++) {
data[i] = "This is element #" + i;
}
return data;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SectionIndexer;
import android.widget.TextView;

import com.example.android.recyclerview.R;
import com.example.recyclerviewfastscroller.data.ColorData;
import com.example.recyclerviewfastscroller.data.ColorDataSet;
import com.example.recyclerviewfastscroller.data.ColorGroup;

/**
* Provide views to RecyclerView with data from mDataSet.
*/
public class ColorfulAdapter extends RecyclerView.Adapter<ColorfulAdapter.ViewHolder> {
public class ColorfulAdapter extends RecyclerView.Adapter<ColorfulAdapter.ViewHolder> implements SectionIndexer {

private static final float NUM_HUES = 359f;

private String[] mDataSet;
private ColorDataSet mDataSet;

/**
* Provide a reference to the type of views that you are using (custom ViewHolder)
Expand Down Expand Up @@ -60,10 +62,10 @@ public TextView getTextView() {
/**
* Initialize the dataset of the Adapter.
*
* @param dataSet String[] containing the data to populate views to be used by RecyclerView.
* @param data String[] containing the data to populate views to be used by RecyclerView.
*/
public ColorfulAdapter(String[] dataSet) {
mDataSet = dataSet;
public ColorfulAdapter(ColorDataSet data) {
mDataSet = data;
}

// Create new views (invoked by the layout manager)
Expand All @@ -78,15 +80,35 @@ public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
// Get element from your dataset at this position and replace the contents of the view
// with that element
float positionBasedHue = position * (NUM_HUES / mDataSet.length);
viewHolder.itemView.setBackgroundColor(Color.HSVToColor(new float[] {positionBasedHue, 1, 1}));
viewHolder.getTextView().setText(mDataSet[position]);
ColorData color = mDataSet.get(position);
viewHolder.itemView.setBackgroundColor(color.getIntValue());
viewHolder.getTextView().setText(mDataSet.get(position).toString());
}

// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataSet.length;
return mDataSet.getSize();
}

@Override
public Object[] getSections() {
return ColorGroup.values();
}

@Override
public int getPositionForSection(int sectionIndex) {
return 0;
}

@Override
public int getSectionForPosition(int position) {
if (position >= mDataSet.getSize()) {
position = mDataSet.getSize() - 1;
}

ColorData color = mDataSet.get(position);
return color.getColorGroup().ordinal();
}

}
Loading

0 comments on commit b3e2d2f

Please sign in to comment.