Skip to content
This repository has been archived by the owner on Jul 28, 2024. It is now read-only.

Commit

Permalink
* Fix wrong position passed when an entry from the list is selected
Browse files Browse the repository at this point in the history
* Add the option to load the datasource from XML
  • Loading branch information
Angelo Marchesin committed Apr 18, 2019
1 parent 113fd5a commit 5904053
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 57 deletions.
73 changes: 52 additions & 21 deletions app/src/main/java/org/angmarc/app/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Toast;

import org.angmarch.views.NiceSpinner;
import org.angmarch.views.SimpleSpinnerTextFormatter;
Expand All @@ -19,21 +22,32 @@ public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupDefault();
setupTintedWithCustomClass();
setupXml();
}

NiceSpinner niceSpinner = findViewById(R.id.nice_spinner);
List<String> dataset = new LinkedList<>(Arrays.asList("One", "Two", "Three", "Four", "Five"));
niceSpinner.attachDataSource(dataset);

NiceSpinner tintedSpinner = findViewById(R.id.tinted_nice_spinner);
tintedSpinner.attachDataSource(dataset);
private void setupXml() {
NiceSpinner spinner = findViewById(R.id.niceSpinnerXml);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String item = parent.getItemAtPosition(position).toString();
Toast.makeText(MainActivity.this, "Selected: " + item, Toast.LENGTH_SHORT).show();
}

NiceSpinner bottomSpinner = findViewById(R.id.bottom_nice_spinner);
@Override
public void onNothingSelected(AdapterView<?> parent) { }
});
}

private void setupTintedWithCustomClass() {
final NiceSpinner spinner = findViewById(R.id.tinted_nice_spinner);
List<Person> persons = new ArrayList<>();

persons.add(new Person("John", "Smith"));
persons.add(new Person("Adam", "Sandler"));
persons.add(new Person("One", "Two"));
persons.add(new Person("Tony", "Stark"));
persons.add(new Person("Steve", "Rogers"));
persons.add(new Person("Bruce", "Banner"));

SimpleSpinnerTextFormatter textFormatter = new SimpleSpinnerTextFormatter() {
@Override
Expand All @@ -43,16 +57,36 @@ public Spannable format(Object item) {
}
};

bottomSpinner.setSpinnerTextFormatter(textFormatter);
bottomSpinner.setSelectedTextFormatter(textFormatter);
spinner.setSpinnerTextFormatter(textFormatter);
spinner.setSelectedTextFormatter(textFormatter);
spinner.addOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Person person = (Person) spinner.getSelectedItem(); //parent.getItemAtPosition(position).toString();
Toast.makeText(MainActivity.this, "Selected: " + person.toString(), Toast.LENGTH_SHORT).show();
}
});
spinner.attachDataSource(persons);
}

bottomSpinner.attachDataSource(persons);
private void setupDefault() {
NiceSpinner spinner = findViewById(R.id.nice_spinner);
List<String> dataset = new LinkedList<>(Arrays.asList("One", "Two", "Three", "Four", "Five"));
spinner.attachDataSource(dataset);
spinner.addOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String item = parent.getItemAtPosition(position).toString();
Toast.makeText(MainActivity.this, "Selected: " + item, Toast.LENGTH_SHORT).show();
}
});
}
}

class Person {
String name;
String surname;

private String name;
private String surname;

Person(String name, String surname) {
this.name = name;
Expand All @@ -63,15 +97,12 @@ String getName() {
return name;
}

void setName(String name) {
this.name = name;
}

String getSurname() {
return surname;
}

void setSurname(String surname) {
this.surname = surname;
@Override
public String toString() {
return name + " " + surname;
}
}
66 changes: 50 additions & 16 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,26 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginTop="8dp"
android:layout_marginRight="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"
app:layout_constraintVertical_bias="0.0" />

<org.angmarch.views.NiceSpinner
android:id="@+id/niceSpinnerXml"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:layout_marginRight="16dp"
app:entries="@array/courses"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView3"
app:layout_constraintVertical_bias="0.0" />

<org.angmarch.views.NiceSpinner
Expand All @@ -33,27 +47,47 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/nice_spinner"
app:layout_constraintTop_toBottomOf="@+id/textView2"
app:layout_constraintVertical_bias="0.0"
app:textTint="@color/colorPrimary" />

<org.angmarch.views.NiceSpinner
android:id="@+id/bottom_nice_spinner"
android:layout_width="0dp"
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="8dp"
app:popupTextAlignment="end"
app:arrowTint="@color/colorPrimary"
app:backgroundSelector="@drawable/background_selector"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="8dp"
android:text="Default"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tinted_nice_spinner"
app:layout_constraintVertical_bias="1.0"
app:textTint="@color/colorPrimary" />
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:text="Tinted with custom class"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/nice_spinner" />

<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:text="Default with data defined in XML"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tinted_nice_spinner" />

</android.support.constraint.ConstraintLayout>
6 changes: 6 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
<resources>
<string name="app_name">Nice Spinner App</string>

<string-array name="courses">
<item>English</item>
<item>Chinese</item>
<item>Math</item>
</string-array>
</resources>
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0-alpha08'
classpath 'com.android.tools.build:gradle:3.5.0-alpha11'
}
}

Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1-milestone-1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-all.zip
34 changes: 24 additions & 10 deletions library/src/main/java/org/angmarch/views/NiceSpinner.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import android.os.Parcelable;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
Expand All @@ -26,6 +27,7 @@
import android.widget.ListView;
import android.widget.PopupWindow;

import java.util.Arrays;
import java.util.List;

/*
Expand Down Expand Up @@ -68,12 +70,14 @@ public class NiceSpinner extends AppCompatTextView {
private int displayHeight;
private int parentVerticalOffset;
private int dropDownListPaddingBottom;
private @DrawableRes int arrowDrawableResId;
private @DrawableRes
int arrowDrawableResId;
private SpinnerTextFormatter spinnerTextFormatter = new SimpleSpinnerTextFormatter();
private SpinnerTextFormatter selectedTextFormatter = new SimpleSpinnerTextFormatter();
private PopUpTextAlignment horizontalAlignment;

@Nullable private ObjectAnimator arrowAnimator = null;
@Nullable
private ObjectAnimator arrowAnimator = null;

public NiceSpinner(Context context) {
super(context);
Expand Down Expand Up @@ -160,13 +164,14 @@ private void init(Context context, AttributeSet attrs) {

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// The selected item is not displayed within the list, so when the selected position is equal to
// the one of the currently selected item it gets shifted to the next item.
int offsetPosition = position;
if (position >= selectedIndex && position < adapter.getCount()) {
position++;
offsetPosition++;
}

// Need to set selected index before calling listeners or getSelectedIndex() can be
// reported incorrectly due to race conditions.
selectedIndex = position;
selectedIndex = offsetPosition;

if (onItemClickListener != null) {
onItemClickListener.onItemClick(parent, view, position, id);
Expand All @@ -176,8 +181,8 @@ public void onItemClick(AdapterView<?> parent, View view, int position, long id)
onItemSelectedListener.onItemSelected(parent, view, position, id);
}

adapter.setSelectedIndex(position);
setTextInternal(selectedTextFormatter.format(adapter.getItemInDataset(position)).toString());
adapter.setSelectedIndex(offsetPosition);
setTextInternal(selectedTextFormatter.format(adapter.getItemInDataset(offsetPosition)).toString());
dismissDropDown();
}
});
Expand Down Expand Up @@ -212,6 +217,11 @@ public void onDismiss() {
typedArray.getInt(R.styleable.NiceSpinner_popupTextAlignment, PopUpTextAlignment.CENTER.ordinal())
);

CharSequence[] entries = typedArray.getTextArray(R.styleable.NiceSpinner_entries);
if (entries != null) {
attachDataSource(Arrays.asList(entries));
}

typedArray.recycle();

measureDisplayHeight();
Expand All @@ -237,7 +247,7 @@ protected void onDetachedFromWindow() {
}
super.onDetachedFromWindow();
}

@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
Expand Down Expand Up @@ -283,6 +293,10 @@ private int getDefaultTextColor(Context context) {
return defaultTextColor;
}

public Object getSelectedItem() {
return adapter.getItemInDataset(selectedIndex);
}

public int getSelectedIndex() {
return selectedIndex;
}
Expand Down Expand Up @@ -331,7 +345,7 @@ public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener onItemS
this.onItemSelectedListener = onItemSelectedListener;
}

public <T> void attachDataSource(List<T> list) {
public <T> void attachDataSource(@NonNull List<T> list) {
adapter = new NiceSpinnerAdapter<>(getContext(), list, textColor, backgroundSelector, spinnerTextFormatter, horizontalAlignment);
setAdapterInternal(adapter);
}
Expand Down
17 changes: 9 additions & 8 deletions library/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="popupTextAlignment" format="enum">
<enum name="start" value="0"/>
<enum name="end" value="1"/>
<enum name="center" value="2"/>
<enum name="start" value="0" />
<enum name="end" value="1" />
<enum name="center" value="2" />
</attr>

<declare-styleable name="NiceSpinner">
<attr name="arrowTint" format="color" />
<attr name="hideArrow" format="boolean" />
<attr name="arrowDrawable" format="reference|color"/>
<attr name="dropDownListPaddingBottom" format="dimension"/>
<attr name="backgroundSelector" format="integer"/>
<attr name="textTint" format="color"/>
<attr name="popupTextAlignment"/>
<attr name="arrowDrawable" format="reference|color" />
<attr name="dropDownListPaddingBottom" format="dimension" />
<attr name="backgroundSelector" format="integer" />
<attr name="textTint" format="color" />
<attr name="popupTextAlignment" />
<attr name="entries" format="reference" />
</declare-styleable>
</resources>

0 comments on commit 5904053

Please sign in to comment.