Slider field
This commit is contained in:
parent
a4038688ce
commit
10fa0047fd
3 changed files with 122 additions and 1 deletions
|
@ -5,6 +5,7 @@ import static eu.siacs.conversations.entities.Bookmark.printableValue;
|
|||
import android.content.Intent;
|
||||
|
||||
import de.monocles.chat.MonoclesViewPager;
|
||||
import eu.siacs.conversations.databinding.CommandSliderFieldBinding;
|
||||
import eu.siacs.conversations.http.HttpConnectionManager;
|
||||
import eu.siacs.conversations.ui.UriHandlerActivity;
|
||||
import android.content.DialogInterface;
|
||||
|
@ -55,6 +56,8 @@ import android.util.DisplayMetrics;
|
|||
import com.caverock.androidsvg.SVG;
|
||||
|
||||
import android.util.SparseBooleanArray;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
@ -2713,6 +2716,65 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
|||
public void onTextChanged(CharSequence s, int start, int count, int after) { }
|
||||
}
|
||||
|
||||
class SliderFieldViewHolder extends ViewHolder<CommandSliderFieldBinding> {
|
||||
public SliderFieldViewHolder(CommandSliderFieldBinding binding) { super(binding); }
|
||||
protected Field field = null;
|
||||
|
||||
@Override
|
||||
public void bind(Item item) {
|
||||
field = (Field) item;
|
||||
setTextOrHide(binding.label, field.getLabel());
|
||||
setTextOrHide(binding.desc, field.getDesc());
|
||||
final Element validate = field.el.findChild("validate", "http://jabber.org/protocol/xdata-validate");
|
||||
final String datatype = validate == null ? null : validate.getAttribute("datatype");
|
||||
final Element range = validate == null ? null : validate.findChild("range", "http://jabber.org/protocol/xdata-validate");
|
||||
final boolean open = validate != null && validate.findChild("open", "http://jabber.org/protocol/xdata-validate") != null;
|
||||
Float min = null;
|
||||
try { min = range.getAttribute("min") == null ? null : Float.valueOf(range.getAttribute("min")); } catch (NumberFormatException e) { }
|
||||
Float max = null;
|
||||
try { max = range.getAttribute("max") == null ? null : Float.valueOf(range.getAttribute("max")); } catch (NumberFormatException e) { }
|
||||
|
||||
List<Float> options = field.getOptions().stream().map(o -> Float.valueOf(o.getValue())).collect(Collectors.toList());
|
||||
Collections.sort(options);
|
||||
if (!open && options.size() > 0) {
|
||||
min = options.get(0);
|
||||
max = options.get(options.size()-1);
|
||||
}
|
||||
|
||||
if (field.getValues().size() > 0) binding.slider.setValue(Float.valueOf(field.getValue().getContent()));
|
||||
binding.slider.setValueFrom(min == null ? Float.MIN_VALUE : min);
|
||||
binding.slider.setValueTo(max == null ? Float.MAX_VALUE : max);
|
||||
if ("xs:integer".equals(datatype) || "xs:int".equals(datatype) || "xs:long".equals(datatype) || "xs:short".equals(datatype) || "xs:byte".equals(datatype)) {
|
||||
binding.slider.setStepSize(1);
|
||||
} else {
|
||||
binding.slider.setStepSize(0);
|
||||
}
|
||||
|
||||
if (!open && options.size() > 0) {
|
||||
float step = -1;
|
||||
Float prev = null;
|
||||
for (final Float option : options) {
|
||||
if (prev != null) {
|
||||
float nextStep = option - prev;
|
||||
if (step > 0 && step != nextStep) {
|
||||
step = -1;
|
||||
break;
|
||||
}
|
||||
step = nextStep;
|
||||
}
|
||||
prev = option;
|
||||
}
|
||||
if (step > 0) binding.slider.setStepSize(step);
|
||||
// NOTE: if step == -1 and !open then the widget will allow illegal values
|
||||
}
|
||||
|
||||
binding.slider.addOnChangeListener((slider, value, fromUser) -> {
|
||||
field.setValues(List.of(new DecimalFormat().format(value)));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class WebViewHolder extends ViewHolder<CommandWebviewBinding> {
|
||||
public WebViewHolder(CommandWebviewBinding binding) { super(binding); }
|
||||
protected String boundUrl = "";
|
||||
|
@ -2879,6 +2941,9 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
|||
if (formType.equals("result") || fieldType.equals("fixed")) {
|
||||
viewType = TYPE_RESULT_FIELD;
|
||||
} else if (formType.equals("form")) {
|
||||
final Element validate = el.findChild("validate", "http://jabber.org/protocol/xdata-validate");
|
||||
final String datatype = validate == null ? null : validate.getAttribute("datatype");
|
||||
final Element range = validate == null ? null : validate.findChild("range", "http://jabber.org/protocol/xdata-validate");
|
||||
if (fieldType.equals("boolean")) {
|
||||
if (fillableFieldCount == 1 && actionsAdapter.countExceptCancel() < 1) {
|
||||
viewType = TYPE_BUTTON_GRID_FIELD;
|
||||
|
@ -2886,7 +2951,14 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
|||
viewType = TYPE_CHECKBOX_FIELD;
|
||||
}
|
||||
} else if (fieldType.equals("list-single")) {
|
||||
Element validate = el.findChild("validate", "http://jabber.org/protocol/xdata-validate");
|
||||
} else if (
|
||||
range != null && (
|
||||
"xs:integer".equals(datatype) || "xs:int".equals(datatype) || "xs:long".equals(datatype) || "xs:short".equals(datatype) || "xs:byte".equals(datatype) ||
|
||||
"xs:decimal".equals(datatype) || "xs:double".equals(datatype)
|
||||
)
|
||||
) {
|
||||
// has a range and is numeric, use a slider
|
||||
viewType = TYPE_SLIDER_FIELD;
|
||||
if (fillableFieldCount == 1 && actionsAdapter.countExceptCancel() < 1) {
|
||||
viewType = TYPE_BUTTON_GRID_FIELD;
|
||||
} else if (Option.forField(el).size() > 9) {
|
||||
|
@ -2992,6 +3064,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
|||
final int TYPE_SEARCH_LIST_FIELD = 11;
|
||||
final int TYPE_ITEM_CARD = 12;
|
||||
final int TYPE_BUTTON_GRID_FIELD = 13;
|
||||
final int TYPE_SLIDER_FIELD = 14;
|
||||
|
||||
protected boolean executing = false;
|
||||
protected boolean loading = false;
|
||||
|
@ -3380,6 +3453,10 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
|||
CommandTextFieldBinding binding = DataBindingUtil.inflate(LayoutInflater.from(container.getContext()), R.layout.command_text_field, container, false);
|
||||
return new TextFieldViewHolder(binding);
|
||||
}
|
||||
case TYPE_SLIDER_FIELD: {
|
||||
CommandSliderFieldBinding binding = DataBindingUtil.inflate(LayoutInflater.from(container.getContext()), R.layout.command_slider_field, container, false);
|
||||
return new SliderFieldViewHolder(binding);
|
||||
}
|
||||
case TYPE_PROGRESSBAR: {
|
||||
CommandProgressBarBinding binding = DataBindingUtil.inflate(LayoutInflater.from(container.getContext()), R.layout.command_progress_bar, container, false);
|
||||
return new ProgressBarViewHolder(binding);
|
||||
|
|
42
src/main/res/layout/command_slider_field.xml
Normal file
42
src/main/res/layout/command_slider_field.xml
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="16dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="13dp"
|
||||
android:paddingRight="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:textAppearance="@style/TextAppearance.Conversations.Subhead"
|
||||
android:textColor="?attr/edit_text_color" />
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/slider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
app:trackColorInactive="?color_background_primary"
|
||||
app:trackColorActive="?colorAccent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/desc"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="8dp"
|
||||
android:textAppearance="@style/TextAppearance.Conversations.Status"
|
||||
android:textColor="?android:textColorSecondary" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</layout>
|
|
@ -41,6 +41,8 @@
|
|||
<item name="colorAccentLight">@color/accent_light</item>
|
||||
<item name="colorAccentLightDisabled">@color/accent_light_disabled</item>
|
||||
<item name="popupOverlayStyle">@style/ThemeOverlay.Material3.Light</item>
|
||||
<item name="colorOnBackground">?colorPrimaryDark</item>
|
||||
<item name="colorSurface">?colorPrimaryDark</item>
|
||||
<item name="colorControlNormal">?attr/text_Color_Main</item>
|
||||
<item name="colorControlActivated">@color/accent</item>
|
||||
<item name="text_Color_Main">@color/realblack</item>
|
||||
|
|
Loading…
Add table
Reference in a new issue