Android sliders with fixed numbers - android

I'm trying to implement a discrete slider with fixed values, but the only thing I can set is the valueFrom, valueTo and stepSize.
Here is my code how I'm trying to do
<com.google.android.material.slider.Slider
android:id="#+id/slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="8dp"
app:tickColor="#color/colorSecondaryLight"
app:tickColorActive="#color/colorSecondary" />
Is there a way to set fixed values on the slider? (Values that I will use 2, 5, 10, 25, 50 and 100)

The solution that worked for me was this lib called BubbleSeekBar
Step 1 - Add the dependencies on your Gradle.
implementation "com.xw.repo:bubbleseekbar:3.20-lite"
Step 2 - Create your BubbleSeekBar on your XML and add the attributes that you need. For my case, the example below worked.
<com.xw.repo.BubbleSeekBar
android:id="#+id/bubbleSeekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:bsb_auto_adjust_section_mark="true"
app:bsb_hide_bubble="true"
app:bsb_min="2"
app:bsb_section_count="5"
app:bsb_section_text_position="below_section_mark"
app:bsb_seek_by_section="true" />
Step 3 - Since I needed custom options, I initialized on my onCreate with the array of values declared on my string.xml
bubbleSeekBar.setCustomSectionTextArray { sectionCount, array ->
array.clear()
for ((index, value) in resources.getStringArray(R.array.xxxx)
.withIndex()) {
array.put(index, value)
}
array
}
Step 4 - You can capture the changes or set a value with the methods below.
bubbleSeekBar.onProgressChangedListener
bubbleSeekBar.setProgress()
The lib is pretty good and worked for me. For more info take a look at the link at the top of this answer.

You'd be better off using SeekBar
<SeekBar
android:id="#+id/sb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="10"
android:thumb="#drawable/ic_location"
android:theme="#style/Widget.AppCompat.SeekBar.Discrete" />

You can use a SeekBar and define the range of values, and in order to remove the smoothness/refining scrolling, set OnSeekBarChangeListener to it and override onProgressChanged() with the valid range of the SeekBar values you need by setting the progress again as below.
Example
Using a SeekBar with a max value of 100, and a step of 10; so the total valid values are 10.
SeekBar seekBar = findViewById(R.id.seekbar);
seekBar.setMax(100);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean
fromUser) {
seekBar.setProgress((progress / 10) * 10);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});

Related

Eclipse Android: I want a letter appear firstly bigger and then getting smaller

In my activity is a TextView with the content "Ecl pse", where the "i" is missing. After I click on a button I want the letter "i" to appear in the right Position. But the "i" should be so animated, that it firstly appears a little bit bigger and then gets smaller until it is as big as the the other letters after I clicked on the button. But momentarily with my code the whole word "Ecl pse" is influenced by the ValueAnimation. It's not only that the "i" is bigger and gets smaller after I clicked on the button, but also the position of the whole word "Ecl pse" changes: "Ecl pse" goes down and then comes back in the origin position. How can i fix that? Again, I want only the letter "i" to appear a little bit bigger and then getting smaller until it is as big as the other letters of the word "Ecl pse" after I clicked on the button...
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tvhallo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="87dp"
android:text="Ecl pse"
android:textSize="70sp" />
<Button
android:id="#+id/BtnKlick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Klick" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/tvhallo"
android:layout_alignBottom="#+id/tvhallo"
android:layout_alignLeft="#+id/BtnKlick"
android:layout_toLeftOf="#+id/BtnKlick"
android:text="i"
android:textSize="70sp" />
</RelativeLayout>
CODE:
public Button btn;
public TextView tw;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.pagetwo);
btn = (Button) findViewById(R.id.BtnKlick);
tw = (TextView) findViewById(R.id.tvhallo);
btn.setOnClickListener(this);}
#SuppressLint("NewApi")
public void onClick(View v) {
// TODO Auto-generated method stub
ValueAnimator animator = new ValueAnimator();
animator.setDuration(2000);
animator.setObjectValues("Ecl pse", "Eclipse");
animator.setEvaluator(new TypeEvaluator<CharSequence>()
{
#Override
public CharSequence evaluate(float fraction, CharSequence startValue, CharSequence endValue)
{
float relativeSize = 4 - 3 * fraction;
Spannable span = new SpannableString("Eclipse");
span.setSpan(new RelativeSizeSpan(relativeSize), 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return span;
}
});
animator.addUpdateListener(new AnimatorUpdateListener()
{
#Override
public void onAnimationUpdate(ValueAnimator animation)
{
tw.setText((CharSequence)animation.getAnimatedValue());
}
});
animator.start();}}
I really doubt a TextView is the right instrument for what you're trying to achieve. It is both overkill and inadequate for the job. It can display all matters of text with various formatting and is for a good reason described as "a complete text editor". It's main purpose is to provide a way to display text, and possibly quite a lot of it (that part was the overkill). Inserting and (potentially) scaling the 'i' will cause the rest of the letters to move, as that is what the class is for. It's intended to layout text, not layout it statically in a way that causes changes to the content to move as little as possible (this is the inadequate part)
But what you actually want is not to display text, but an animation. I would recommend you create the text you want in any imaging program with various states: one without the 'i', a few with it too large and scaling down, and a final image with the correct proportions. Now use these images do display the animation triggered by pressing the button. I believe the correct class for this task would be AnimationDrawable, though I haven't used it myself. There are certainly numerous ways on how to get the exact behavior you want, but I hope this'll get you started!

SeekBar: ProgressDrawable does only show after first progress Change

I want to implement a easy hsv color picker that fit well into my app. As known form color Pickers I would like to change the background of the seekBars according to the value of the other seekBars.
But when I start the activity I am seeing this:
After the first touch of one of the seekBars (no matter which) I get this result and after the first touch the layout stays like this and does not change with further touches (which is also what I would have expected according to my layout, the 2 seekBars on top are 20dip and the 1 below is as high as the thumb):
Like seen in the second picture I would like to have the seekBar from beginning.
Here my layout:
<SeekBar
android:id="#+id/SbColorPickerHue"
android:layout_width="match_parent"
android:layout_height="20dip"
android:max="360"
android:thumb="#drawable/colorpickerthumb" />
<SeekBar
android:id="#+id/SbColorPickerSaturation"
android:layout_width="match_parent"
android:layout_height="20dip"
android:max="255"
android:thumb="#drawable/colorpickerthumb"/>
<SeekBar
android:id="#+id/SbColorPickerValue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:thumb="#drawable/colorpickerthumb"/>
With a OnSeekBarChangeListener in onProgressChanged() and of course in onCreate (to initalize the seekBars) I am calling the following function (To safe you a lot of code only the Hue Gradient is shown):
private void setGradients() {
mHueGradient = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT,mColors);
mHueGradient.setGradientType(GradientDrawable.LINEAR_GRADIENT);
mHueGradient.setCornerRadius(mRadius);
mHueGradient.setStroke(mStrokeWidth, mStrokeColor);
mSbHue.setBackgroundDrawable(mHueGradient);
}
I tried many different things already:
set the Gradients twice in onCreate
set the Gradients again in onRescume
as can be seen in the layout xml I set some of the SeekBar to a fixed height (20dp) and others to wrap_content. The behaviour changed a little (as can be seen in the pictures). But still not satisfying.
Invalidate either the seekBar or the Drawable
Force Layout
Measure the drawable
Result is always the same.
What am I doing wrong here? Am I missing somthing?
Edit 1:
The SeekBar and the ChangeListener are defined as follows:
mSbHue = (SeekBar)findViewById(R.id.SbColorPickerHue);
setGradients();
mSbHue.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onStopTrackingTouch(SeekBar seekBar) {
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
setGradients();
}
});
If you move setGradients() after the listener it works.
mSbHue = (SeekBar)findViewById(R.id.SbColorPickerHue);
mSbHue.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onStopTrackingTouch(SeekBar seekBar) {
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
setGradients();
}
});
setGradients();

How to change Android SeekBar track start position?

I'd like to set the SeekBars's track start position so it does not start from the left side of the seekbar, but form an arbitrary position. Here is a photoshop image how it should look like:
http://i.imgur.com/QCMEu.png
It should be just a graphical effect, the SeekBar's underlying logic is not changed.
I tried to change the Seekbar.getprogressDrawable.SetBounds() to change the track image position, but no luck.
add this proprety
android:progress="2"
You can set progress of SeekBar in xml as:
android:progress="10"
android:max="90" <!-- maximum seekbar progress -->
you can programmatically set the progress of SeekBar as:
seekBar.setProgress(10);
May be your problem is similar to Seekbar for two values [-50, 0, 50].
Thanks to Commonsware to point to right direction. I wrote a class inspired by code.google.com/p/range-seek-bar) to get the solution.
https://github.com/vashisthg/StartPointSeekBar
By Programatically,we can start the progress and set the maximum of seekbar progress.
//start from <starting value>
seekBar.setProgress(<strating_value>);
//Set to maximum Value<max_value>
seekBar.setMax(<max_value>);
You can add this:
android:rotation="180"
to the XML and then the seekbar will flip the way you want
Just faced the same problem.
That's how I have solved it.
Assume, we need seekbar starting from 10 and ending at 150.
#Override
protected void onCreate(Bundle savedInstanceState)
{...
yourSpinner = (Spinner) findViewById(R.id.your_spinner);
yourSpinner.setMax(150 - 10);
int newProgress;
yourSpinner.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
{
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
newProgress= 10 + progress;
Toast.makeText(getApplicationContext(), String.valueOf(newProgress), Toast.LENGTH_LONG).show();
}
});
}

Seekbars and EditTexts

I am working on an application in which I need the user to set an array of 30 values and to make it user friendly and easy to use I have decided to use a series of SeekBars and EditText widgets. I am using eclipse and have used it to set up the layout.
I am looking for an efficient way to set up the application to automatically update the value of the SeekBar when the value of the EditText has been changed and then use that same value in a application integer array.
<SeekBar android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:max="255"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:padding="10dp"
android:id="#+id/seekX"></SeekBar>
<EditText android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".01"
android:minWidth="50sp"
android:maxWidth="50sp"
android:gravity="center_horizontal"
android:padding="10dp"
android:layout_marginRight="10dp"
android:inputType="number"
android:id="#+id/editX"></EditText>
The seek bars and EditText fields are named in a corresponding way editX should match seekX as editY should match seekY and so on. I am also storing the values in the int[] upgradeValues.
I have also set the SeekBar to have a max of 255 but i need a way to automatically change any value set in the EditText field above 255 down to 255 and similarly any value below 0 to 0.
Basically I need an efficient way of making "(ValueOF)seekX = (ValueOf)editX = (ValueOf)upgradeValues[x] >= 0 <= 255" and be updated if seekX or editX is changed.
I am still pretty new to Android development, so this answer isn't very specific, but hopefully it gets you on your way.
There are a few approaches. You can set change listeners on both of your seekbar and the edittext that update the values of the other (suppose you have your EditText t, SeekBar b and the value in model:
b.setOnSeekBarChangeListener(new OnSeekBarChangeListener()
{
#Override
public void onProgressChanged(final SeekBar seekBar,
final int progress,
final boolean fromUser)
{
if (fromUser)
{
model = progress;
updateUI();
}
}
#Override
public void onStartTrackingTouch(final SeekBar seekBar)
{
}
#Override
public void onStopTrackingTouch(final SeekBar seekBar)
{
}
});
t.setOnKeyListener(new View.OnKeyListener()
{
#Override
public boolean onKey(final View v,
final int keyCode,
final KeyEvent event)
{
model = Integer.parseInt(t.getText().toString());
updateUI();
return true;
}
});
Then updateUI() would be something like:
private void updateUI()
{
t.setText(model);
b.setProgress(model);
}
Those are some crazy names and I clearly did no error checking. But you get the idea. This is probably NOT the way you want to go, because you have to make sure you catch all the different ways the user interacts with each component (onKey probably isn't enough to detect whenever the EditText value changes).
The proper (MVC) way is to have your model (your int[]) contain the value and have your SeekBar and EditText use your model as their models. I don't know how to do that in Android's UI model.

Unclickable Seekbar in android listview

I have a Listview in my application. Listview rows are clickable. I have introduced a seek bar in each row of a Listview. Despite settings android:clickable="false" for Seekbar in layout xml, I am still able to click on it and move seek bar as desired. I don't want Seekbar to be clickbale but I do want Listview row to clickable.
Any pointers will be appreciated.
Here's my layout file
android:progressDrawable="#drawable/slider_range"
android:thumb="#drawable/slider_thumb"
android:layout_width="80dip"
android:layout_height="12dip"
android:focusable="false"
android:clickable="false"
android:longClickable="false"
seekBarObj.setOnSeekBarChangeListener( new OnSeekBarChangeListener() {
int originalProgress;
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
//Nothing here..
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
originalProgress = seekBar.getProgress();
}
#Override
public void onProgressChanged(SeekBar seekBar, int arg1, boolean fromUser) {
if( fromUser == true){
seekBar.setProgress( originalProgress);
}
}
});
Try setting the enabled attribute to false. You may have to manually adjust the color if you want to avoid it appearing "greyed out"
e.g.
seekBar.setEnabled(false);
I've now got this working using both setFocusable and setEnabled to false, I've implemented a solution to enable the seekbar for a single adjustment when the list item is clicked too if you are interested.
Add focusable=false to the seekbar.

Categories

Resources