From fd5f46f2439636ad933c65a37e93148cd5c6ebf4 Mon Sep 17 00:00:00 2001 From: Mathias-Boulay Date: Tue, 16 May 2023 12:19:22 +0200 Subject: [PATCH] Syle[control]: use consistent mapping dropdown --- .../handleview/EditControlPopup.java | 274 ++++++++++-------- .../drawable/background_control_editor.xml | 8 +- .../layout/dialog_control_button_setting.xml | 163 +++++++---- 3 files changed, 274 insertions(+), 171 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java index b61bf40bb..222bdafa5 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java @@ -20,7 +20,6 @@ import android.view.animation.Interpolator; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.CheckBox; -import android.widget.CompoundButton; import android.widget.EditText; import android.widget.SeekBar; import android.widget.Spinner; @@ -45,56 +44,54 @@ import java.util.List; * Class providing a sort of popup on top of a Layout, allowing to edit a given ControlButton */ public class EditControlPopup { + protected final Spinner[] mKeycodeSpinners = new Spinner[4]; private final DefocusableScrollView mScrollView; - private ConstraintLayout mRootView; private final ColorSelector mColorSelector; private final ObjectAnimator mEditPopupAnimator; private final ObjectAnimator mColorEditorAnimator; - private boolean mDisplaying = false; - private boolean mDisplayingColor = false; - public boolean internalChanges = false; // True when we programmatically change stuff. - private ControlInterface mCurrentlyEditedButton; private final int mMargin; + public boolean internalChanges = false; // True when we programmatically change stuff. private final View.OnLayoutChangeListener mLayoutChangedListener = new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { - if(internalChanges) return; + if (internalChanges) return; internalChanges = true; - int width = (int)(safeParseFloat(mWidthEditText.getText().toString())); + int width = (int) (safeParseFloat(mWidthEditText.getText().toString())); - if(width >= 0 && Math.abs(right - width) > 1){ + if (width >= 0 && Math.abs(right - width) > 1) { mWidthEditText.setText(String.valueOf(right - left)); } - int height = (int)(safeParseFloat(mHeightEditText.getText().toString())); - if(height >= 0 && Math.abs(bottom - height) > 1){ + int height = (int) (safeParseFloat(mHeightEditText.getText().toString())); + if (height >= 0 && Math.abs(bottom - height) > 1) { mHeightEditText.setText(String.valueOf(bottom - top)); } internalChanges = false; } }; - protected EditText mNameEditText, mWidthEditText, mHeightEditText; @SuppressLint("UseSwitchCompatOrMaterialCode") protected Switch mToggleSwitch, mPassthroughSwitch, mSwipeableSwitch; protected Spinner mOrientationSpinner; - protected final Spinner[] mKeycodeSpinners = new Spinner[4]; + protected TextView[] mKeycodeTextviews = new TextView[4]; protected SeekBar mStrokeWidthSeekbar, mCornerRadiusSeekbar, mAlphaSeekbar; protected TextView mStrokePercentTextView, mCornerRadiusPercentTextView, mAlphaPercentTextView; protected TextView mSelectBackgroundColor, mSelectStrokeColor; protected ArrayAdapter mAdapter; protected List mSpecialArray; protected CheckBox mDisplayInGameCheckbox, mDisplayInMenuCheckbox; - + private ConstraintLayout mRootView; + private boolean mDisplaying = false; + private boolean mDisplayingColor = false; + private ControlInterface mCurrentlyEditedButton; // Decorative textviews private TextView mOrientationTextView, mMappingTextView, mNameTextView, mCornerRadiusTextView, mVisibilityTextView, mSizeTextview, mSizeXTextView; - - public EditControlPopup(Context context, ViewGroup parent){ + public EditControlPopup(Context context, ViewGroup parent) { mScrollView = (DefocusableScrollView) LayoutInflater.from(context).inflate(R.layout.dialog_control_button_setting, parent, false); parent.addView(mScrollView); @@ -121,18 +118,23 @@ public class EditControlPopup { setupRealTimeListeners(); } + public static void setPercentageText(TextView textView, int progress) { + textView.setText(textView.getContext().getString(R.string.percent_format, progress)); + } - /** Slide the layout into the visible screen area */ - public void appear(boolean fromRight){ + /** + * Slide the layout into the visible screen area + */ + public void appear(boolean fromRight) { disappearColor(); // When someone jumps from a button to another - if(fromRight){ - if(!mDisplaying || !isAtRight()){ + if (fromRight) { + if (!mDisplaying || !isAtRight()) { mEditPopupAnimator.setFloatValues(currentDisplayMetrics.widthPixels, currentDisplayMetrics.widthPixels - mScrollView.getWidth() - mMargin); mEditPopupAnimator.start(); } - }else{ - if (!mDisplaying || isAtRight()){ + } else { + if (!mDisplaying || isAtRight()) { mEditPopupAnimator.setFloatValues(-mScrollView.getWidth(), mMargin); mEditPopupAnimator.start(); } @@ -141,12 +143,14 @@ public class EditControlPopup { mDisplaying = true; } - /** Slide out the layout */ - public void disappear(){ - if(!mDisplaying) return; + /** + * Slide out the layout + */ + public void disappear() { + if (!mDisplaying) return; mDisplaying = false; - if(isAtRight()) + if (isAtRight()) mEditPopupAnimator.setFloatValues(currentDisplayMetrics.widthPixels - mScrollView.getWidth() - mMargin, currentDisplayMetrics.widthPixels); else mEditPopupAnimator.setFloatValues(mMargin, -mScrollView.getWidth()); @@ -154,15 +158,17 @@ public class EditControlPopup { mEditPopupAnimator.start(); } - /** Slide the layout into the visible screen area */ - public void appearColor(boolean fromRight, int color){ - if(fromRight){ - if(!mDisplayingColor || !isAtRight()){ + /** + * Slide the layout into the visible screen area + */ + public void appearColor(boolean fromRight, int color) { + if (fromRight) { + if (!mDisplayingColor || !isAtRight()) { mColorEditorAnimator.setFloatValues(currentDisplayMetrics.widthPixels, currentDisplayMetrics.widthPixels - mScrollView.getWidth() - mMargin); mColorEditorAnimator.start(); } - }else{ - if (!mDisplayingColor || isAtRight()){ + } else { + if (!mDisplayingColor || isAtRight()) { mColorEditorAnimator.setFloatValues(-mScrollView.getWidth(), mMargin); mColorEditorAnimator.start(); } @@ -172,12 +178,14 @@ public class EditControlPopup { mColorSelector.show(color == -1 ? Color.WHITE : color); } - /** Slide out the layout */ - public void disappearColor(){ - if(!mDisplayingColor) return; + /** + * Slide out the layout + */ + public void disappearColor() { + if (!mDisplayingColor) return; mDisplayingColor = false; - if(isAtRight()) + if (isAtRight()) mColorEditorAnimator.setFloatValues(currentDisplayMetrics.widthPixels - mScrollView.getWidth() - mMargin, currentDisplayMetrics.widthPixels); else mColorEditorAnimator.setFloatValues(mMargin, -mScrollView.getWidth()); @@ -185,33 +193,37 @@ public class EditControlPopup { mColorEditorAnimator.start(); } - /** Slide out the first visible layer. - * @return True if the last layer is disappearing */ - public boolean disappearLayer(){ - if(mDisplayingColor){ + /** + * Slide out the first visible layer. + * + * @return True if the last layer is disappearing + */ + public boolean disappearLayer() { + if (mDisplayingColor) { disappearColor(); return false; - }else{ + } else { disappear(); return true; } } - /** Switch the panels position if needed */ - public void adaptPanelPosition(){ - if(mDisplaying){ - boolean isAtRight = mCurrentlyEditedButton.getControlView().getX() + mCurrentlyEditedButton.getControlView().getWidth()/2f < currentDisplayMetrics.widthPixels/2f; + /** + * Switch the panels position if needed + */ + public void adaptPanelPosition() { + if (mDisplaying) { + boolean isAtRight = mCurrentlyEditedButton.getControlView().getX() + mCurrentlyEditedButton.getControlView().getWidth() / 2f < currentDisplayMetrics.widthPixels / 2f; appear(isAtRight); } } - - public void destroy(){ + public void destroy() { ((ViewGroup) mScrollView.getParent()).removeView(mColorSelector.getRootView()); ((ViewGroup) mScrollView.getParent()).removeView(mScrollView); } - private void loadAdapter(){ + private void loadAdapter() { //Initialize adapter for keycodes mAdapter = new ArrayAdapter<>(mRootView.getContext(), R.layout.item_centered_textview); mSpecialArray = ControlData.buildSpecialButtonArray(); @@ -232,27 +244,22 @@ public class EditControlPopup { mOrientationSpinner.setAdapter(adapter); } - - - private void setDefaultVisibilitySetting(){ - for(int i=0; i currentDisplayMetrics.widthPixels/2f; - } - - - public static void setPercentageText(TextView textView, int progress){ - textView.setText(textView.getContext().getString(R.string.percent_format, progress)); + private boolean isAtRight() { + return mScrollView.getX() > currentDisplayMetrics.widthPixels / 2f; } /* LOADING VALUES */ - /** Load values for basic control data */ - public void loadValues(ControlData data){ + /** + * Load values for basic control data + */ + public void loadValues(ControlData data) { setDefaultVisibilitySetting(); mOrientationTextView.setVisibility(GONE); mOrientationSpinner.setVisibility(GONE); @@ -261,11 +268,11 @@ public class EditControlPopup { mWidthEditText.setText(String.valueOf(data.getWidth())); mHeightEditText.setText(String.valueOf(data.getHeight())); - mAlphaSeekbar.setProgress((int) (data.opacity*100)); + mAlphaSeekbar.setProgress((int) (data.opacity * 100)); mStrokeWidthSeekbar.setProgress(data.strokeWidth); mCornerRadiusSeekbar.setProgress((int) data.cornerRadius); - setPercentageText(mAlphaPercentTextView, (int) (data.opacity*100)); + setPercentageText(mAlphaPercentTextView, (int) (data.opacity * 100)); setPercentageText(mStrokePercentTextView, data.strokeWidth); setPercentageText(mCornerRadiusPercentTextView, (int) data.cornerRadius); @@ -276,7 +283,7 @@ public class EditControlPopup { mDisplayInGameCheckbox.setChecked(data.displayInGame); mDisplayInMenuCheckbox.setChecked(data.displayInMenu); - for(int i = 0; i< data.keycodes.length; i++){ + for (int i = 0; i < data.keycodes.length; i++) { if (data.keycodes[i] < 0) { mKeycodeSpinners[i].setSelection(data.keycodes[i] + mSpecialArray.size()); } else { @@ -285,18 +292,20 @@ public class EditControlPopup { } } - /** Load values for extended control data */ - public void loadValues(ControlDrawerData data){ + /** + * Load values for extended control data + */ + public void loadValues(ControlDrawerData data) { loadValues(data.properties); mOrientationSpinner.setSelection( ControlDrawerData.orientationToInt(data.orientation)); mMappingTextView.setVisibility(GONE); - mKeycodeSpinners[0].setVisibility(GONE); - mKeycodeSpinners[1].setVisibility(GONE); - mKeycodeSpinners[2].setVisibility(GONE); - mKeycodeSpinners[3].setVisibility(GONE); + for (int i = 0; i < mKeycodeSpinners.length; i++) { + mKeycodeSpinners[i].setVisibility(GONE); + mKeycodeTextviews[i].setVisibility(GONE); + } mOrientationTextView.setVisibility(VISIBLE); mOrientationSpinner.setVisibility(VISIBLE); @@ -306,15 +315,17 @@ public class EditControlPopup { mToggleSwitch.setVisibility(View.GONE); } - /** Load values for the joystick */ - public void loadJoystickValues(ControlData data){ + /** + * Load values for the joystick + */ + public void loadJoystickValues(ControlData data) { loadValues(data); mMappingTextView.setVisibility(GONE); - mKeycodeSpinners[0].setVisibility(GONE); - mKeycodeSpinners[1].setVisibility(GONE); - mKeycodeSpinners[2].setVisibility(GONE); - mKeycodeSpinners[3].setVisibility(GONE); + for (int i = 0; i < mKeycodeSpinners.length; i++) { + mKeycodeSpinners[i].setVisibility(GONE); + mKeycodeTextviews[i].setVisibility(GONE); + } mNameTextView.setVisibility(GONE); mNameEditText.setVisibility(GONE); @@ -328,8 +339,10 @@ public class EditControlPopup { mToggleSwitch.setVisibility(View.GONE); } - /** Load values for sub buttons */ - public void loadSubButtonValues(ControlData data){ + /** + * Load values for sub buttons + */ + public void loadSubButtonValues(ControlData data) { loadValues(data); // Size linked to the parent drawer @@ -345,7 +358,7 @@ public class EditControlPopup { } - private void bindLayout(){ + private void bindLayout() { mRootView = mScrollView.findViewById(R.id.edit_layout); mNameEditText = mScrollView.findViewById(R.id.editName_editText); mWidthEditText = mScrollView.findViewById(R.id.editSize_editTextX); @@ -357,6 +370,10 @@ public class EditControlPopup { mKeycodeSpinners[1] = mScrollView.findViewById(R.id.editMapping_spinner_2); mKeycodeSpinners[2] = mScrollView.findViewById(R.id.editMapping_spinner_3); mKeycodeSpinners[3] = mScrollView.findViewById(R.id.editMapping_spinner_4); + mKeycodeTextviews[0] = mScrollView.findViewById(R.id.mapping_1_textview); + mKeycodeTextviews[1] = mScrollView.findViewById(R.id.mapping_2_textview); + mKeycodeTextviews[2] = mScrollView.findViewById(R.id.mapping_3_textview); + mKeycodeTextviews[3] = mScrollView.findViewById(R.id.mapping_4_textview); mOrientationSpinner = mScrollView.findViewById(R.id.editOrientation_spinner); mStrokeWidthSeekbar = mScrollView.findViewById(R.id.editStrokeWidth_seekbar); mCornerRadiusSeekbar = mScrollView.findViewById(R.id.editCornerRadius_seekbar); @@ -383,16 +400,19 @@ public class EditControlPopup { * A long function linking all the displayed data on the popup and, * the currently edited mCurrentlyEditedButton */ - public void setupRealTimeListeners(){ + public void setupRealTimeListeners() { mNameEditText.addTextChangedListener(new TextWatcher() { @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} + public void onTextChanged(CharSequence s, int start, int before, int count) { + } @Override public void afterTextChanged(Editable s) { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().name = s.toString(); @@ -403,16 +423,19 @@ public class EditControlPopup { mWidthEditText.addTextChangedListener(new TextWatcher() { @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} + public void onTextChanged(CharSequence s, int start, int before, int count) { + } @Override public void afterTextChanged(Editable s) { - if(internalChanges) return; + if (internalChanges) return; float width = safeParseFloat(s.toString()); - if(width >= 0){ + if (width >= 0) { mCurrentlyEditedButton.getProperties().setWidth(width); mCurrentlyEditedButton.updateProperties(); } @@ -421,16 +444,19 @@ public class EditControlPopup { mHeightEditText.addTextChangedListener(new TextWatcher() { @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} + public void onTextChanged(CharSequence s, int start, int before, int count) { + } @Override public void afterTextChanged(Editable s) { - if(internalChanges) return; + if (internalChanges) return; float height = safeParseFloat(s.toString()); - if(height >= 0){ + if (height >= 0) { mCurrentlyEditedButton.getProperties().setHeight(height); mCurrentlyEditedButton.updateProperties(); } @@ -438,66 +464,77 @@ public class EditControlPopup { }); mSwipeableSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().isSwipeable = isChecked; }); mToggleSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().isToggle = isChecked; }); mPassthroughSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().passThruEnabled = isChecked; }); mAlphaSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if(internalChanges) return; - mCurrentlyEditedButton.getProperties().opacity = mAlphaSeekbar.getProgress()/100f; - mCurrentlyEditedButton.getControlView().setAlpha(mAlphaSeekbar.getProgress()/100f); + if (internalChanges) return; + mCurrentlyEditedButton.getProperties().opacity = mAlphaSeekbar.getProgress() / 100f; + mCurrentlyEditedButton.getControlView().setAlpha(mAlphaSeekbar.getProgress() / 100f); setPercentageText(mAlphaPercentTextView, progress); } @Override - public void onStartTrackingTouch(SeekBar seekBar) {} + public void onStartTrackingTouch(SeekBar seekBar) { + } + @Override - public void onStopTrackingTouch(SeekBar seekBar) {} + public void onStopTrackingTouch(SeekBar seekBar) { + } }); mStrokeWidthSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().strokeWidth = mStrokeWidthSeekbar.getProgress(); mCurrentlyEditedButton.setBackground(); setPercentageText(mStrokePercentTextView, progress); } @Override - public void onStartTrackingTouch(SeekBar seekBar) {} + public void onStartTrackingTouch(SeekBar seekBar) { + } + @Override - public void onStopTrackingTouch(SeekBar seekBar) {} + public void onStopTrackingTouch(SeekBar seekBar) { + } }); mCornerRadiusSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().cornerRadius = mCornerRadiusSeekbar.getProgress(); mCurrentlyEditedButton.setBackground(); setPercentageText(mCornerRadiusPercentTextView, progress); } @Override - public void onStartTrackingTouch(SeekBar seekBar) {} + public void onStartTrackingTouch(SeekBar seekBar) { + } + @Override - public void onStopTrackingTouch(SeekBar seekBar) {} + public void onStopTrackingTouch(SeekBar seekBar) { + } }); - for(int i = 0; i< mKeycodeSpinners.length; ++i){ + for (int i = 0; i < mKeycodeSpinners.length; ++i) { int finalI = i; + mKeycodeTextviews[i].setOnClickListener(v -> mKeycodeSpinners[finalI].performClick()); + mKeycodeSpinners[i].setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { @@ -508,10 +545,12 @@ public class EditControlPopup { } else { mCurrentlyEditedButton.getProperties().keycodes[finalI] = EfficientAndroidLWJGLKeycode.getValueByIndex(mKeycodeSpinners[finalI].getSelectedItemPosition() - mSpecialArray.size()); } + mKeycodeTextviews[finalI].setText((String) mKeycodeSpinners[finalI].getSelectedItem()); } @Override - public void onNothingSelected(AdapterView parent) {} + public void onNothingSelected(AdapterView parent) { + } }); } @@ -522,23 +561,24 @@ public class EditControlPopup { // Side note, spinner listeners are fired later than all the other ones. // Meaning the internalChanges bool is useless here. - if(mCurrentlyEditedButton instanceof ControlDrawer){ - ((ControlDrawer)mCurrentlyEditedButton).drawerData.orientation = ControlDrawerData.intToOrientation(mOrientationSpinner.getSelectedItemPosition()); - ((ControlDrawer)mCurrentlyEditedButton).syncButtons(); + if (mCurrentlyEditedButton instanceof ControlDrawer) { + ((ControlDrawer) mCurrentlyEditedButton).drawerData.orientation = ControlDrawerData.intToOrientation(mOrientationSpinner.getSelectedItemPosition()); + ((ControlDrawer) mCurrentlyEditedButton).syncButtons(); } } @Override - public void onNothingSelected(AdapterView parent) {} + public void onNothingSelected(AdapterView parent) { + } }); mDisplayInGameCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().displayInGame = isChecked; }); mDisplayInMenuCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().displayInMenu = isChecked; }); @@ -561,18 +601,18 @@ public class EditControlPopup { }); } - private float safeParseFloat(String string){ + private float safeParseFloat(String string) { float out = -1; // -1 try { out = Float.parseFloat(string); - }catch (NumberFormatException e){ + } catch (NumberFormatException e) { Log.e("EditControlPopup", e.toString()); } return out; } - public void setCurrentlyEditedButton(ControlInterface button){ - if(mCurrentlyEditedButton != null) + public void setCurrentlyEditedButton(ControlInterface button) { + if (mCurrentlyEditedButton != null) mCurrentlyEditedButton.getControlView().removeOnLayoutChangeListener(mLayoutChangedListener); mCurrentlyEditedButton = button; mCurrentlyEditedButton.getControlView().addOnLayoutChangeListener(mLayoutChangedListener); diff --git a/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml b/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml index f661cb029..90c07e23d 100644 --- a/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml +++ b/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml @@ -3,9 +3,9 @@ android:shape="rectangle"> + android:bottom="@dimen/_2sdp" + android:left="@dimen/_2sdp" + android:right="@dimen/_2sdp" + android:top="@dimen/_2sdp" /> diff --git a/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml b/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml index 1bbb7dabc..bf2dfc9b9 100644 --- a/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml +++ b/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml @@ -56,7 +56,7 @@ + app:layout_constraintTop_toBottomOf="@+id/editMapping_textView" /> + + + + + + + + + + + - - - + app:layout_constraintBottom_toBottomOf="@+id/mapping_1_textview" + app:layout_constraintEnd_toEndOf="@+id/mapping_1_textview" + app:layout_constraintStart_toEndOf="@id/mapping_1_textview" + app:layout_constraintTop_toTopOf="@+id/mapping_1_textview" /> - - + + + app:layout_constraintTop_toBottomOf="@id/mapping_1_textview" + + tools:text="HELLO" /> + app:layout_constraintBottom_toBottomOf="@+id/mapping_3_textview" + app:layout_constraintEnd_toEndOf="@+id/mapping_3_textview" + app:layout_constraintStart_toEndOf="@id/mapping_3_textview" + app:layout_constraintTop_toBottomOf="@+id/mapping_1_textview" /> - + app:layout_constraintStart_toEndOf="@id/mapping_3_textview" + app:layout_constraintTop_toTopOf="@id/mapping_3_textview" + + tools:text="HELLO" />