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.
Related
Is there a way to set the color of a progressBar in XML, while the progress is going on?
I want to change the color of my progress at 80% to red.
Is there a way to to this in xml? So I just can copy paste my progressBar without coding it manually everytime...
No, you cannot change the color at runtime using xml.
If you can change your ProgressBar to SeekBar, you can easily listen to the progress change & as it reaches 80, you can change the color.
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
I have a seekbar in a listview, it is disabled to stop the user from changing the value whilst scrolling the list. I wish to enable it if the list item is long clicked, allow the user to change it and then disable it again.
Any suggestions.
I seem unable to access the seekbar from the activity as it is setup inside the ArrayAdapter to display a value from the database
I am able to fire a both a click event and a long click event for the list item, as the seekbar is currently disabled.
Solution
In the ArrayAdapter I set both enabled and focusable to false and added the SeekBar listener, setting the attributes to false allowed me to use the list item onItemClicked listener. Inside the onItemCLickListener I retreived the seekbar, set the attributes to true, this meant it could be slid up or down. I then disabled it after the adjustment had been made. code below
ArrayAdapter Snippet
this code is inside the creation of the list item, in which the seekbar is housed
seekBar.setClickable(false);
seekBar.setFocusable(false);
seekBar.setEnabled(false);
/* attach listener */
attachProgressUpdatedListener(seekBar, positionOfItemInList);
AttachProgressUpdatedListener
this method attaches the listener to the seekbar, inside the arrayAdapter class
private void attachProgressUpdatedListener(SeekBar seekBar,
final int position) {
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onStopTrackingTouch(SeekBar seekBar) {
int progress = seekBar.getProgress();
int task_id = (Integer) seekBar.getTag();
TaskHandler taskHandler = new TaskHandler(DBAdapter
.getDBAdapterInstance(getContext()));
taskHandler.updateTaskProgress(task_id, progress);
mList.get(position).setProgress(progress);
//need to fire an update to the activity
notifyDataSetChanged();
seekBar.setEnabled(false);
}
public void onStartTrackingTouch(SeekBar seekBar) {
// empty as onStartTrackingTouch listener not being used in
// current implementation
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// empty as onProgressChanged listener not being used in
// current implementation
}
});
}
OnItemCLickListener
this snipped is from the activity which houses the list view.
taskListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
SeekBar sb = (SeekBar) view.findViewById(R.id.seek);
sb.setFocusable(true);
sb.setEnabled(true);
}
});
I had overcame this issue by setting the following attributes to the seekbar in listview item layout file. Then I had the click event of listitem and seekbar working.
android:focusable="false"
android:focusableInTouchMode="false"
<SeekBar
android:id="#+id/playback_icon"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:progress="0"
android:progressDrawable="#drawable/red_scrubber_progress"
android:thumb="#drawable/red_scrubber_control"
android:focusable="false"
android:focusableInTouchMode="false"/>
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.