Implemented string attribute value editor in UI Designer

This commit is contained in:
Akash Yadav
2022-03-16 18:11:16 +05:30
parent 28dd445496
commit 46753711ac
7 changed files with 192 additions and 44 deletions
+1
View File
@@ -62,6 +62,7 @@
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/app/src/main/res/layout/layout_editor_bottom_sheet.xml" value="0.19572649572649573" />
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/app/src/main/res/layout/layout_editor_text_actions.xml" value="0.25" />
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/app/src/main/res/layout/layout_resource_input_field.xml" value="0.25" />
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/app/src/main/res/layout/layout_string_attr_editor.xml" value="0.25" />
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/app/src/main/res/layout/layout_symbol_item.xml" value="0.20512820512820512" />
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/app/src/main/res/layout/layout_text_action_item.xml" value="0.42168674698795183" />
<entry key="..\:/Projects/AndroidStudioProjects/AndroidIDE/app/src/main/res/layout/test.xml" value="0.20512820512820512" />
Binary file not shown.
@@ -31,6 +31,7 @@ import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
/**
* Adapter for showing the autocomplete items while editing attribute values in UI Designer.
@@ -72,6 +73,11 @@ public class AttrValueCompletionAdapter extends BaseAdapter implements Filterabl
CharSequence constraint, @NonNull FilterResults results) {
//noinspection unchecked
List<String> items = (List<String>) results.values;
Objects.requireNonNull (items);
filtered.clear ();
filtered.addAll (items);
if (items.isEmpty ()) {
notifyDataSetInvalidated ();
} else {
@@ -14,7 +14,6 @@
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.fragments.attr;
import static com.itsaky.androidide.utils.Logger.instance;
@@ -36,68 +35,70 @@ import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
/** @author Akash Yadav */
/**
* @author Akash Yadav
*/
public class ReferenceEditor extends BaseValueEditorFragment {
private static final Logger LOG = instance("ReferenceEditor");
private static final Logger LOG = instance ("ReferenceEditor");
public TextWatcherAdapter resInputWatcher;
@Override
protected void notifyValueChanged(@NonNull String newValue) {
protected void notifyValueChanged (@NonNull String newValue) {
try {
super.notifyValueChanged(newValue);
super.notifyValueChanged (newValue);
} catch (Throwable e) {
LOG.error("Unable to update resource value to '" + newValue + "'", e);
LOG.error ("Unable to update resource value to '" + newValue + "'", e);
}
}
protected void setupReferenceInput(MaterialAutoCompleteTextView referenceInput) {
Objects.requireNonNull(referenceInput);
protected void setupReferenceInput (MaterialAutoCompleteTextView referenceInput) {
Objects.requireNonNull (referenceInput);
if (resInputWatcher != null) {
referenceInput.removeTextChangedListener(resInputWatcher);
referenceInput.removeTextChangedListener (resInputWatcher);
}
resInputWatcher =
new TextWatcherAdapter() {
new TextWatcherAdapter () {
@Override
public void afterTextChanged(@NonNull Editable s) {
final var text = s.toString().trim();
if (TextUtils.isEmpty(text)) {
public void afterTextChanged (@NonNull Editable s) {
final var text = s.toString ().trim ();
if (TextUtils.isEmpty (text)) {
return;
}
notifyValueChanged(text);
notifyValueChanged (text);
}
};
referenceInput.addTextChangedListener(resInputWatcher);
CompletableFuture.supplyAsync(this::computeReferenceItems)
.whenComplete(
(list, error) -> handleAutoCompleteResult(list, error, referenceInput));
referenceInput.addTextChangedListener (resInputWatcher);
CompletableFuture.supplyAsync (this::computeReferenceItems)
.whenComplete (
(list, error) -> handleAutoCompleteResult (list, error, referenceInput));
}
protected void handleAutoCompleteResult(
protected void handleAutoCompleteResult (
List<String> list, Throwable error, AutoCompleteTextView referenceInput) {
if (list == null || list.isEmpty()) {
LOG.error("No completion items found");
LOG.error("Error was:", error);
if (list == null || list.isEmpty ()) {
LOG.error ("No completion items found");
LOG.error ("Error was:", error);
return;
}
LOG.debug("Found", list.size(), "resource items for completion");
ThreadUtils.runOnUiThread(
LOG.debug ("Found", list.size (), "resource items for completion");
ThreadUtils.runOnUiThread (
() -> {
final var adapter = new AttrValueCompletionAdapter(requireContext(), list);
referenceInput.setThreshold(1);
referenceInput.setAdapter(adapter);
adapter.notifyDataSetChanged();
final var adapter = new AttrValueCompletionAdapter (requireContext (), list);
referenceInput.setThreshold (1);
referenceInput.setAdapter (adapter);
adapter.notifyDataSetChanged ();
});
}
protected List<String> computeReferenceItems() {
return new ArrayList<>();
protected List<String> computeReferenceItems () {
return new ArrayList<> ();
}
}
@@ -14,10 +14,74 @@
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.fragments.attr;
import android.os.Bundle;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.textfield.MaterialAutoCompleteTextView;
import com.itsaky.androidide.databinding.LayoutStringAttrEditorBinding;
import com.itsaky.androidide.utils.TextWatcherAdapter;
import com.itsaky.inflater.values.FrameworkValues;
import com.itsaky.inflater.values.ValuesTableFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @author Akash Yadav
*/
public class StringEditor extends BaseValueEditorFragment {}
public class StringEditor extends ReferenceEditor {
private LayoutStringAttrEditorBinding binding;
@Nullable
@Override
public View onCreateView (@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
this.binding = LayoutStringAttrEditorBinding.inflate (inflater, container, false);
return this.binding.getRoot ();
}
@Override
public void onViewCreated (@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated (view, savedInstanceState);
Objects.requireNonNull (this.binding.stringInput.getEditText ()).addTextChangedListener (new TextWatcherAdapter () {
@Override
public void afterTextChanged (@NonNull Editable s) {
notifyValueChanged (s.toString ());
}
});
setupReferenceInput ((MaterialAutoCompleteTextView) this.binding.stringResInput.getEditText ());
}
@Override
protected List<String> computeReferenceItems () {
final var list = new ArrayList<String> ();
final var tables = ValuesTableFactory.getAllTables ();
for (var entry : tables.entrySet ()) {
final var dimens = entry.getValue ().getTable ("string");
if (dimens != null) {
list.addAll (
dimens.keySet ().stream ()
.map ("@string/"::concat)
.collect (Collectors.toSet ()));
}
}
list.addAll (
FrameworkValues.listDimens ().stream ()
.map ("@android:string/"::concat)
.collect (Collectors.toList ()));
return list;
}
}
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:padding="16dp">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/string_input"
style="@style/AppTheme.TextInputLayout.Outlined"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="@string/hint_string_value"
app:hintEnabled="true"
app:hintTextColor="@color/secondaryColor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.google.android.material.textfield.TextInputLayout>
<View
android:id="@+id/divider1"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_margin="16dp"
android:background="@color/primaryLightColor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/string_input" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/string_res_input"
style="@style/AppTheme.TextInputLayout.Outlined"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:hint="@string/hint_string_resource"
app:hintEnabled="true"
app:hintTextColor="@color/secondaryColor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/divider1">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:layout_width="match_parent"
android:layout_height="56dp"
android:digits="abcdefghijklmnopqrstwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_/@"
android:inputType="textNoSuggestions"
android:padding="16dp" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
+2
View File
@@ -340,4 +340,6 @@
<string name="msg_file_tree">File tree</string>
<string name="hint_color_resource">Color resource</string>
<string name="title_color_picker">Color picker</string>
<string name="hint_string_value">String value</string>
<string name="hint_string_resource">String resource</string>
</resources>