Merge pull request #11163 from t895/convert-layout

Android: Replace spinners with dropdown menus
This commit is contained in:
JosJuice 2022-10-23 20:00:18 +02:00 committed by GitHub
commit 7743afddac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 279 additions and 255 deletions

View File

@ -4,7 +4,6 @@ package org.dolphinemu.dolphinemu.features.riivolution.ui;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
@ -49,18 +48,8 @@ public class RiivolutionAdapter extends RecyclerView.Adapter<RiivolutionViewHold
public RiivolutionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType)
{
case RiivolutionViewHolder.TYPE_HEADER:
View headerView = inflater.inflate(R.layout.list_item_riivolution_header, parent, false);
return new RiivolutionViewHolder(headerView);
case RiivolutionViewHolder.TYPE_OPTION:
View optionView = inflater.inflate(R.layout.list_item_riivolution_option, parent, false);
return new RiivolutionViewHolder(optionView);
default:
throw new UnsupportedOperationException();
}
return new RiivolutionViewHolder(
inflater.inflate(R.layout.list_item_riivolution, parent, false));
}
@Override
@ -74,11 +63,4 @@ public class RiivolutionAdapter extends RecyclerView.Adapter<RiivolutionViewHold
{
return mItems.size();
}
@Override
public int getItemViewType(int position)
{
return mItems.get(position).mOptionIndex != -1 ?
RiivolutionViewHolder.TYPE_OPTION : RiivolutionViewHolder.TYPE_HEADER;
}
}

View File

@ -6,24 +6,23 @@ import android.content.Context;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textfield.MaterialAutoCompleteTextView;
import com.google.android.material.textfield.TextInputLayout;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.riivolution.model.RiivolutionPatches;
public class RiivolutionViewHolder extends RecyclerView.ViewHolder
implements AdapterView.OnItemSelectedListener
implements AdapterView.OnItemClickListener
{
public static final int TYPE_HEADER = 0;
public static final int TYPE_OPTION = 1;
private final TextView mTextView;
private final Spinner mSpinner;
private final TextInputLayout mChoiceLayout;
private final MaterialAutoCompleteTextView mChoiceDropdown;
private RiivolutionPatches mPatches;
private RiivolutionItem mItem;
@ -32,18 +31,34 @@ public class RiivolutionViewHolder extends RecyclerView.ViewHolder
super(itemView);
mTextView = itemView.findViewById(R.id.text_name);
mSpinner = itemView.findViewById(R.id.spinner_choice);
mChoiceLayout = itemView.findViewById(R.id.layout_choice);
mChoiceDropdown = itemView.findViewById(R.id.dropdown_choice);
}
public void bind(Context context, RiivolutionPatches patches, RiivolutionItem item)
{
// TODO: Remove workaround for text filtering issue in material components when fixed
// https://github.com/material-components/material-components-android/issues/1464
mChoiceDropdown.setSaveEnabled(false);
String text;
if (item.mOptionIndex != -1)
{
mTextView.setVisibility(View.GONE);
text = patches.getOptionName(item.mDiscIndex, item.mSectionIndex, item.mOptionIndex);
mChoiceLayout.setHint(text);
}
else if (item.mSectionIndex != -1)
{
mTextView.setTextAppearance(context, R.style.TextAppearance_AppCompat_Medium);
mChoiceLayout.setVisibility(View.GONE);
text = patches.getSectionName(item.mDiscIndex, item.mSectionIndex);
}
else
{
mChoiceLayout.setVisibility(View.GONE);
text = patches.getDiscName(item.mDiscIndex);
}
mTextView.setText(text);
if (item.mOptionIndex != -1)
@ -52,10 +67,10 @@ public class RiivolutionViewHolder extends RecyclerView.ViewHolder
mItem = item;
ArrayAdapter<String> adapter = new ArrayAdapter<>(context,
R.layout.list_item_riivolution_header);
R.layout.support_simple_spinner_dropdown_item);
int choiceCount = patches.getChoiceCount(mItem.mDiscIndex, mItem.mSectionIndex,
mItem.mOptionIndex);
int choiceCount =
patches.getChoiceCount(mItem.mDiscIndex, mItem.mSectionIndex, mItem.mOptionIndex);
adapter.add(context.getString(R.string.riivolution_disabled));
for (int i = 0; i < choiceCount; i++)
{
@ -63,21 +78,17 @@ public class RiivolutionViewHolder extends RecyclerView.ViewHolder
i));
}
mSpinner.setAdapter(adapter);
mSpinner.setSelection(patches.getSelectedChoice(mItem.mDiscIndex, mItem.mSectionIndex,
mItem.mOptionIndex));
mSpinner.setOnItemSelectedListener(this);
mChoiceDropdown.setAdapter(adapter);
mChoiceDropdown.setText(adapter.getItem(
patches.getSelectedChoice(mItem.mDiscIndex, mItem.mSectionIndex, mItem.mOptionIndex)),
false);
mChoiceDropdown.setOnItemClickListener(this);
}
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
mPatches.setSelectedChoice(mItem.mDiscIndex, mItem.mSectionIndex, mItem.mOptionIndex, position);
}
@Override
public void onNothingSelected(AdapterView<?> parent)
{
}
}

View File

@ -14,7 +14,6 @@ import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.Spinner;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
@ -23,6 +22,8 @@ import androidx.fragment.app.Fragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import com.google.android.material.textfield.MaterialAutoCompleteTextView;
import com.google.android.material.textfield.TextInputLayout;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
@ -35,25 +36,19 @@ import java.util.ArrayList;
public class ConvertFragment extends Fragment implements View.OnClickListener
{
private static class SpinnerValue implements AdapterView.OnItemSelectedListener
private static class DropdownValue implements AdapterView.OnItemClickListener
{
private int mValuesId = -1;
private int mCurrentPosition = -1;
private int mCurrentPosition = 0;
private ArrayList<Runnable> mCallbacks = new ArrayList<>();
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id)
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
if (mCurrentPosition != position)
setPosition(position);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView)
{
mCurrentPosition = -1;
}
int getPosition()
{
return mCurrentPosition;
@ -102,7 +97,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
private static final int REQUEST_CODE_SAVE_FILE = 0;
private static final int BLOB_TYPE_PLAIN = 0;
private static final int BLOB_TYPE_ISO = 0;
private static final int BLOB_TYPE_GCZ = 3;
private static final int BLOB_TYPE_WIA = 7;
private static final int BLOB_TYPE_RVZ = 8;
@ -114,10 +109,20 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
private static final int COMPRESSION_LZMA2 = 4;
private static final int COMPRESSION_ZSTD = 5;
private SpinnerValue mFormat = new SpinnerValue();
private SpinnerValue mBlockSize = new SpinnerValue();
private SpinnerValue mCompression = new SpinnerValue();
private SpinnerValue mCompressionLevel = new SpinnerValue();
private DropdownValue mFormat = new DropdownValue();
private DropdownValue mBlockSize = new DropdownValue();
private DropdownValue mCompression = new DropdownValue();
private DropdownValue mCompressionLevel = new DropdownValue();
private TextInputLayout mFormatLayout;
private MaterialAutoCompleteTextView mFormatDropdown;
private TextInputLayout mBlockSizeLayout;
private MaterialAutoCompleteTextView mBlockSizeDropdown;
private TextInputLayout mCompressionLayout;
private MaterialAutoCompleteTextView mCompressionDropdown;
private TextInputLayout mCompressionLevelLayout;
private MaterialAutoCompleteTextView mCompressionLevelDropdown;
private CheckBox mRemoveJunkDataCheckbox;
private GameFile gameFile;
@ -142,7 +147,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_convert, container, false);
@ -151,6 +156,15 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState)
{
findViews();
// TODO: Remove workaround for text filtering issue in material components when fixed
// https://github.com/material-components/material-components-android/issues/1464
mFormatDropdown.setSaveEnabled(false);
mBlockSizeDropdown.setSaveEnabled(false);
mCompressionDropdown.setSaveEnabled(false);
mCompressionLevelDropdown.setSaveEnabled(false);
populateFormats();
populateBlockSize();
populateCompression();
@ -159,6 +173,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
mFormat.addCallback(this::populateBlockSize);
mFormat.addCallback(this::populateCompression);
mFormat.addCallback(this::populateCompressionLevel);
mCompression.addCallback(this::populateCompressionLevel);
mFormat.addCallback(this::populateRemoveJunkData);
@ -166,19 +181,31 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
if (savedInstanceState != null)
{
setSpinnerSelection(R.id.spinner_format, mFormat, savedInstanceState.getInt(KEY_FORMAT));
setSpinnerSelection(R.id.spinner_block_size, mBlockSize,
setDropdownSelection(mFormatDropdown, mFormat, savedInstanceState.getInt(KEY_FORMAT));
setDropdownSelection(mBlockSizeDropdown, mBlockSize,
savedInstanceState.getInt(KEY_BLOCK_SIZE));
setSpinnerSelection(R.id.spinner_compression, mCompression,
setDropdownSelection(mCompressionDropdown, mCompression,
savedInstanceState.getInt(KEY_COMPRESSION));
setSpinnerSelection(R.id.spinner_compression_level, mCompressionLevel,
setDropdownSelection(mCompressionLevelDropdown, mCompressionLevel,
savedInstanceState.getInt(KEY_COMPRESSION_LEVEL));
CheckBox removeJunkData = requireView().findViewById(R.id.checkbox_remove_junk_data);
removeJunkData.setChecked(savedInstanceState.getBoolean(KEY_REMOVE_JUNK_DATA));
mRemoveJunkDataCheckbox.setChecked(savedInstanceState.getBoolean(KEY_REMOVE_JUNK_DATA));
}
}
private void findViews()
{
mFormatLayout = requireView().findViewById(R.id.format);
mFormatDropdown = requireView().findViewById(R.id.dropdown_format);
mBlockSizeLayout = requireView().findViewById(R.id.block_size);
mBlockSizeDropdown = requireView().findViewById(R.id.dropdown_block_size);
mCompressionLayout = requireView().findViewById(R.id.compression);
mCompressionDropdown = requireView().findViewById(R.id.dropdown_compression);
mCompressionLevelLayout = requireView().findViewById(R.id.compression_level);
mCompressionLevelDropdown = requireView().findViewById(R.id.dropdown_compression_level);
mRemoveJunkDataCheckbox = requireView().findViewById(R.id.checkbox_remove_junk_data);
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState)
{
@ -187,14 +214,17 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
outState.putInt(KEY_COMPRESSION, mCompression.getPosition());
outState.putInt(KEY_COMPRESSION_LEVEL, mCompressionLevel.getPosition());
CheckBox removeJunkData = requireView().findViewById(R.id.checkbox_remove_junk_data);
outState.putBoolean(KEY_REMOVE_JUNK_DATA, removeJunkData.isChecked());
outState.putBoolean(KEY_REMOVE_JUNK_DATA, mRemoveJunkDataCheckbox.isChecked());
}
private void setSpinnerSelection(int id, SpinnerValue valueWrapper, int i)
private void setDropdownSelection(MaterialAutoCompleteTextView dropdown,
DropdownValue valueWrapper, int selection)
{
((Spinner) requireView().findViewById(id)).setSelection(i);
valueWrapper.setPosition(i);
if (dropdown.getAdapter() != null)
{
dropdown.setText(dropdown.getAdapter().getItem(selection).toString(), false);
}
valueWrapper.setPosition(selection);
}
@Override
@ -206,47 +236,41 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
joinThread();
}
private Spinner populateSpinner(int spinnerId, int entriesId, int valuesId,
SpinnerValue valueWrapper)
private void populateDropdown(TextInputLayout layout, MaterialAutoCompleteTextView dropdown,
int entriesId, int valuesId, DropdownValue valueWrapper)
{
Spinner spinner = requireView().findViewById(spinnerId);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(requireContext(),
entriesId, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setEnabled(spinner.getCount() > 1);
entriesId, R.layout.support_simple_spinner_dropdown_item);
dropdown.setAdapter(adapter);
valueWrapper.populate(valuesId);
valueWrapper.setPosition(spinner.getSelectedItemPosition());
spinner.setOnItemSelectedListener(valueWrapper);
dropdown.setOnItemClickListener(valueWrapper);
return spinner;
layout.setEnabled(adapter.getCount() > 1);
}
private Spinner clearSpinner(int spinnerId, SpinnerValue valueWrapper)
private void clearDropdown(TextInputLayout layout, MaterialAutoCompleteTextView dropdown,
DropdownValue valueWrapper)
{
Spinner spinner = requireView().findViewById(spinnerId);
spinner.setAdapter(null);
spinner.setEnabled(false);
dropdown.setAdapter(null);
layout.setEnabled(false);
valueWrapper.populate(-1);
valueWrapper.setPosition(-1);
spinner.setOnItemSelectedListener(valueWrapper);
return spinner;
valueWrapper.setPosition(0);
dropdown.setText(null, false);
dropdown.setOnItemClickListener(valueWrapper);
}
private void populateFormats()
{
Spinner spinner = populateSpinner(R.id.spinner_format, R.array.convertFormatEntries,
populateDropdown(mFormatLayout, mFormatDropdown, R.array.convertFormatEntries,
R.array.convertFormatValues, mFormat);
if (gameFile.getBlobType() == BLOB_TYPE_PLAIN)
spinner.setSelection(spinner.getCount() - 1);
if (gameFile.getBlobType() == BLOB_TYPE_ISO)
{
setDropdownSelection(mFormatDropdown, mFormat, mFormatDropdown.getAdapter().getCount() - 1);
}
mFormatDropdown.setText(mFormatDropdown.getAdapter().getItem(mFormat.getPosition()).toString(),
false);
}
private void populateBlockSize()
@ -257,19 +281,25 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
// In the equivalent DolphinQt code, we have some logic for avoiding block sizes that can
// trigger bugs in Dolphin versions older than 5.0-11893, but it was too annoying to port.
// TODO: Port it?
populateSpinner(R.id.spinner_block_size, R.array.convertBlockSizeGczEntries,
populateDropdown(mBlockSizeLayout, mBlockSizeDropdown, R.array.convertBlockSizeGczEntries,
R.array.convertBlockSizeGczValues, mBlockSize);
mBlockSize.setPosition(0);
mBlockSizeDropdown.setText(mBlockSizeDropdown.getAdapter().getItem(0).toString(), false);
break;
case BLOB_TYPE_WIA:
populateSpinner(R.id.spinner_block_size, R.array.convertBlockSizeWiaEntries,
populateDropdown(mBlockSizeLayout, mBlockSizeDropdown, R.array.convertBlockSizeWiaEntries,
R.array.convertBlockSizeWiaValues, mBlockSize);
mBlockSize.setPosition(0);
mBlockSizeDropdown.setText(mBlockSizeDropdown.getAdapter().getItem(0).toString(), false);
break;
case BLOB_TYPE_RVZ:
populateSpinner(R.id.spinner_block_size, R.array.convertBlockSizeRvzEntries,
R.array.convertBlockSizeRvzValues, mBlockSize).setSelection(2);
populateDropdown(mBlockSizeLayout, mBlockSizeDropdown, R.array.convertBlockSizeRvzEntries,
R.array.convertBlockSizeRvzValues, mBlockSize);
mBlockSize.setPosition(2);
mBlockSizeDropdown.setText(mBlockSizeDropdown.getAdapter().getItem(2).toString(), false);
break;
default:
clearSpinner(R.id.spinner_block_size, mBlockSize);
clearDropdown(mBlockSizeLayout, mBlockSizeDropdown, mBlockSize);
}
}
@ -278,19 +308,31 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
switch (mFormat.getValue(requireContext()))
{
case BLOB_TYPE_GCZ:
populateSpinner(R.id.spinner_compression, R.array.convertCompressionGczEntries,
R.array.convertCompressionGczValues, mCompression);
populateDropdown(mCompressionLayout, mCompressionDropdown,
R.array.convertCompressionGczEntries, R.array.convertCompressionGczValues,
mCompression);
mCompression.setPosition(0);
mCompressionDropdown.setText(mCompressionDropdown.getAdapter().getItem(0).toString(),
false);
break;
case BLOB_TYPE_WIA:
populateSpinner(R.id.spinner_compression, R.array.convertCompressionWiaEntries,
R.array.convertCompressionWiaValues, mCompression);
populateDropdown(mCompressionLayout, mCompressionDropdown,
R.array.convertCompressionWiaEntries, R.array.convertCompressionWiaValues,
mCompression);
mCompression.setPosition(0);
mCompressionDropdown.setText(mCompressionDropdown.getAdapter().getItem(0).toString(),
false);
break;
case BLOB_TYPE_RVZ:
populateSpinner(R.id.spinner_compression, R.array.convertCompressionRvzEntries,
R.array.convertCompressionRvzValues, mCompression).setSelection(4);
populateDropdown(mCompressionLayout, mCompressionDropdown,
R.array.convertCompressionRvzEntries, R.array.convertCompressionRvzValues,
mCompression);
mCompression.setPosition(4);
mCompressionDropdown.setText(mCompressionDropdown.getAdapter().getItem(4).toString(),
false);
break;
default:
clearSpinner(R.id.spinner_compression, mCompression);
clearDropdown(mCompressionLayout, mCompressionDropdown, mCompression);
}
}
@ -301,16 +343,24 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
case COMPRESSION_BZIP2:
case COMPRESSION_LZMA:
case COMPRESSION_LZMA2:
populateSpinner(R.id.spinner_compression_level, R.array.convertCompressionLevelEntries,
R.array.convertCompressionLevelValues, mCompressionLevel).setSelection(4);
populateDropdown(mCompressionLevelLayout, mCompressionLevelDropdown,
R.array.convertCompressionLevelEntries, R.array.convertCompressionLevelValues,
mCompressionLevel);
mCompressionLevel.setPosition(4);
mCompressionLevelDropdown.setText(
mCompressionLevelDropdown.getAdapter().getItem(4).toString(), false);
break;
case COMPRESSION_ZSTD:
// TODO: Query DiscIO for the supported compression levels, like we do in DolphinQt?
populateSpinner(R.id.spinner_compression_level, R.array.convertCompressionLevelZstdEntries,
R.array.convertCompressionLevelZstdValues, mCompressionLevel).setSelection(4);
populateDropdown(mCompressionLevelLayout, mCompressionLevelDropdown,
R.array.convertCompressionLevelZstdEntries,
R.array.convertCompressionLevelZstdValues, mCompressionLevel);
mCompressionLevel.setPosition(4);
mCompressionLevelDropdown.setText(
mCompressionLevelDropdown.getAdapter().getItem(4).toString(), false);
break;
default:
clearSpinner(R.id.spinner_compression_level, mCompressionLevel);
clearDropdown(mCompressionLevelLayout, mCompressionLevelDropdown, mCompressionLevel);
}
}
@ -319,22 +369,15 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
boolean scrubbingAllowed = mFormat.getValue(requireContext()) != BLOB_TYPE_RVZ &&
!gameFile.isDatelDisc();
CheckBox removeJunkData = requireView().findViewById(R.id.checkbox_remove_junk_data);
removeJunkData.setEnabled(scrubbingAllowed);
mRemoveJunkDataCheckbox.setEnabled(scrubbingAllowed);
if (!scrubbingAllowed)
removeJunkData.setChecked(false);
}
private boolean getRemoveJunkData()
{
CheckBox checkBoxScrub = requireView().findViewById(R.id.checkbox_remove_junk_data);
return checkBoxScrub.isChecked();
mRemoveJunkDataCheckbox.setChecked(false);
}
@Override
public void onClick(View view)
{
boolean scrub = getRemoveJunkData();
boolean scrub = mRemoveJunkDataCheckbox.isChecked();
int format = mFormat.getValue(requireContext());
Runnable action = this::showSavePrompt;
@ -350,7 +393,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
action = addAreYouSureDialog(action, R.string.convert_warning_gcz);
}
if (scrub && format == BLOB_TYPE_PLAIN)
if (scrub && format == BLOB_TYPE_ISO)
{
action = addAreYouSureDialog(action, R.string.convert_warning_iso);
}
@ -381,7 +424,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
filename.setLength(dotIndex);
switch (mFormat.getValue(requireContext()))
{
case BLOB_TYPE_PLAIN:
case BLOB_TYPE_ISO:
filename.append(".iso");
break;
case BLOB_TYPE_GCZ:
@ -439,7 +482,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
boolean success = NativeLibrary.ConvertDiscImage(gameFile.getPath(), outPath,
gameFile.getPlatform(), mFormat.getValue(context), mBlockSize.getValueOr(context, 0),
mCompression.getValueOr(context, 0), mCompressionLevel.getValueOr(context, 0),
getRemoveJunkData(), (text, completion) ->
mRemoveJunkDataCheckbox.isChecked(), (text, completion) ->
{
requireActivity().runOnUiThread(() ->
{

View File

@ -1,123 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:layout_height="match_parent">
<TextView
android:id="@+id/label_format"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="@string/convert_format"
app:layout_constraintTop_toTopOf="@id/spinner_format"
app:layout_constraintBottom_toBottomOf="@id/spinner_format"
app:layout_constraintStart_toStartOf="parent" />
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:id="@+id/format"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/convert_format"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/label_block_size"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="@string/convert_block_size"
app:layout_constraintTop_toTopOf="@id/spinner_block_size"
app:layout_constraintBottom_toBottomOf="@id/spinner_block_size"
app:layout_constraintStart_toStartOf="parent" />
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/dropdown_format"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none" />
<TextView
android:id="@+id/label_compression"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="@string/convert_compression"
app:layout_constraintTop_toTopOf="@id/spinner_compression"
app:layout_constraintBottom_toBottomOf="@id/spinner_compression"
app:layout_constraintStart_toStartOf="parent" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/label_compression_level"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="@string/convert_compression_level"
app:layout_constraintTop_toTopOf="@id/spinner_compression_level"
app:layout_constraintBottom_toBottomOf="@id/spinner_compression_level"
app:layout_constraintStart_toStartOf="parent" />
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:id="@+id/block_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/convert_block_size"
android:enabled="false"
app:layout_constraintTop_toBottomOf="@id/format">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/dropdown_block_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:id="@+id/compression"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/convert_compression"
android:enabled="false"
app:layout_constraintTop_toBottomOf="@id/block_size">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/dropdown_compression"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:id="@+id/compression_level"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/convert_compression_level"
android:enabled="false"
app:layout_constraintTop_toBottomOf="@id/compression">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/dropdown_compression_level"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/label_remove_junk_data"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical"
android:text="@string/convert_remove_junk_data"
android:layout_marginStart="@dimen/spacing_small"
app:layout_constraintTop_toTopOf="@id/checkbox_remove_junk_data"
app:layout_constraintBottom_toBottomOf="@id/checkbox_remove_junk_data"
app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/label_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="label_format,label_block_size,label_compression,label_compression_level" />
<Spinner
android:id="@+id/spinner_format"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toEndOf="@id/label_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Spinner
android:id="@+id/spinner_block_size"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:gravity="end"
app:layout_constraintStart_toEndOf="@id/label_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/spinner_format" />
<Spinner
android:id="@+id/spinner_compression"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:gravity="end"
app:layout_constraintStart_toEndOf="@id/label_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/spinner_block_size" />
<Spinner
android:id="@+id/spinner_compression_level"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:gravity="end"
app:layout_constraintStart_toEndOf="@id/label_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/spinner_compression" />
<CheckBox
android:id="@+id/checkbox_remove_junk_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="16dp"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@id/label_remove_junk_data"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/spinner_compression_level" />
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintTop_toBottomOf="@id/compression_level" />
<Button
android:id="@+id/button_convert"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/convert_convert"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/checkbox_remove_junk_data" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/label_remove_junk_data" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/text_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/layout_choice"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginHorizontal="@dimen/spacing_large"
android:layout_marginStart="16dp"
android:layout_marginVertical="@dimen/spacing_medlarge"
android:layout_toStartOf="@+id/layout_choice"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
tools:text="Example Option" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/layout_choice"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="@dimen/spacing_medlarge"
android:layout_marginHorizontal="@dimen/spacing_large"
android:layout_marginTop="0dp">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/dropdown_choice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>
</RelativeLayout>

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/text_name"
tools:text="Example Section"
android:paddingHorizontal="@dimen/spacing_large"
android:paddingVertical="@dimen/spacing_medlarge" />

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/text_name"
tools:text="Example Option"
android:layout_marginHorizontal="@dimen/spacing_large"
android:layout_marginVertical="@dimen/spacing_medlarge"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/spinner_choice"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<Spinner
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/spinner_choice"
app:layout_constraintStart_toEndOf="@id/text_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>