I have a SeekBar in one of my activites in my app.
That seekbar gives me an importance of the object I create. Importance can be 0,1 or 2.
I'd like to dinamically change the background color of my SeekBar when I'm using it. How can I do that ?
Here are the colors I'd like to use :
Importance 0 : "#ff8080"
Importance 1 :"#ff0000"
Importance 2 :"#4d0000"
Thank you for your help, and tell me if you need more code !
BarreImportance.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if(i==0)
{ //it does not accept my colors..
BarreImportance.getProgressDrawable().setColorFilter(Color.parseColor("#ff8080"));
}
if(i==1)
{
//it changes the whole background, not what I want... BarreImportance.setBackgroundColor(Color.parseColor("#ff0000"));
}
You need to use OnSeekBarChangeListener's onProgressChanged callback and change the color from inside there like this: mySeekBar.getProgressDrawable().setColorFilter(..) and mySeekBar.getThumb().setColorFilter(..)
Related
I am implementig UI Tests using espresso.
My boss wants me to check that after a certain action a linearLayout has a new and the correct color. I've wrote a custom matcher which looks like this
public static Matcher<View> withBgColor(final int color) {
Checks.checkNotNull(color);
return new BoundedMatcher<View, LinearLayout>(LinearLayout.class) {
#Override
public boolean matchesSafely(LinearLayout layout) {
MyLog.debug(String.valueOf(color) + " vs " + String.valueOf(((ColorDrawable) layout.getBackground()).getColor()));
return color == ((ColorDrawable) layout.getBackground()).getColor();
//return color == (((PaintDrawable) layout.getBackground()).getPaint()).getColor();
}
#Override
public void describeTo(Description description) {
description.appendText("With background color: ");
}
};
}
My problem is that the comparison of the provided color and the color from the background are not the same. In the app I can see that the right color is set. It is done like this:
holder.linearLayout.setBackgroundColor(ctx.getResources().getColor(R.color.grey_300));
As soon as the test tries to compare the values they differ from each other:
Log: CustomMatcher: 17170432 vs -2039584
I call the matcher like this
.check(matches(withBgColor(R.color.grey_300)));
Can anyone help me how I can check if the color matches? The way I did fails everytime... Thanks
The problem is that both a color and a color resource ID are implemented as integers. You are passing the value of R.color.grey_300, which is a generated number representing the resource ID, instead of the color itself.
You should instead match in this way:
.check(matches(withBgColor(context.getColor(R.color.grey_300))));
If you are worried that getColor() is deprecated, use ContextCompat.getColor(context, R.color.grey_300) instead.
I successfully followed the YouTube tutorial to draw a PieChart in my app using MPAndroidChart, giving each slice of the pie its own color.
I created an OnChartValueSelectedListener so I can know which slice of the pie has been clicked on by the user, like in the following :
public class MyActivity implements OnChartValueSelectedListener {
#Override
public void onNothingSelected() {
// do stuff
}
#Override
public void onValueSelected(Entry e, int dataSetIndex, Highlight h){
Log.i("I clicked on", String.valueOf(e.getXIndex()));
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
...
(PieChart)chart = (PieChart) findViewById(R.id.chart);
...
chart.setOnChartValueSelectedListener(this);
}
}
But even by knowing which slice has been clicked on, I don't seem to find a way to change its color.
The official doc (https://github.com/PhilJay/MPAndroidChart/wiki/Setting-Colors) gives us a way to define and change colors, but only for a dataset, and it seems that a PieChart only have one dataset, so if I change the color of the dataset, every other sliced will see their color changing.
So, I want to know if there is a way, in the following listener
public void onValueSelected(Entry e, int dataSetIndex, Highlight h)
to change the color of the slice which has been clicked on ?
Is it a problem you have already faced ?
Thats quite simple.
Just replace the color value you have set for the DataSet object with a new one.
// get the color(s) you provided for the chart
List<Integer> colors = chart.getData().getDataSetByIndex(dataSetIndex).getColors();
int newcolor = Color.RED;
colors.set(e.getXIndex(), newcolor); // replace the color at the specified index
chart.invalidate(); // refresh
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();
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();
}
});
}
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.