diff options
| author | JosJuice <josjuice@gmail.com> | 2022-10-29 17:20:08 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-29 17:20:08 +0200 |
| commit | aeb0fcb8abdcd8cec3aa36b0c43753ecdf876800 (patch) | |
| tree | f00e015d2d5fabca28af55df61ba9b6b74e300f7 /Source/Android/app/src/main/java/org | |
| parent | 7d55e9f9c7ba347f97b92338511944a83a2eb187 (diff) | |
| parent | 5c30f65bbba66eacc16694e81827f75e1982ec43 (diff) | |
Merge pull request #11092 from t895/view-binding
Android: Use view binding
Diffstat (limited to 'Source/Android/app/src/main/java/org')
41 files changed, 674 insertions, 835 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/ConvertActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/ConvertActivity.java index 2ba35c4d26..49e0687c61 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/ConvertActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/ConvertActivity.java @@ -5,17 +5,12 @@ package org.dolphinemu.dolphinemu.activities; import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.view.View; import androidx.appcompat.app.AppCompatActivity; import androidx.core.view.WindowCompat; -import androidx.core.widget.NestedScrollView; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; -import com.google.android.material.appbar.MaterialToolbar; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ActivityConvertBinding; import org.dolphinemu.dolphinemu.fragments.ConvertFragment; import org.dolphinemu.dolphinemu.utils.InsetsHelper; import org.dolphinemu.dolphinemu.utils.ThemeHelper; @@ -38,7 +33,8 @@ public class ConvertActivity extends AppCompatActivity super.onCreate(savedInstanceState); - setContentView(R.layout.activity_convert); + ActivityConvertBinding binding = ActivityConvertBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); WindowCompat.setDecorFitsSystemWindows(getWindow(), false); @@ -52,17 +48,13 @@ public class ConvertActivity extends AppCompatActivity getSupportFragmentManager().beginTransaction().add(R.id.fragment_convert, fragment).commit(); } - MaterialToolbar tb = findViewById(R.id.toolbar_convert); - CollapsingToolbarLayout ctb = findViewById(R.id.toolbar_convert_layout); - ctb.setTitle(getString(R.string.convert_convert)); - setSupportActionBar(tb); + binding.toolbarConvertLayout.setTitle(getString(R.string.convert_convert)); + setSupportActionBar(binding.toolbarConvert); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - AppBarLayout appBarLayout = findViewById(R.id.appbar_convert); - NestedScrollView scrollView = findViewById(R.id.scroll_view_convert); - View workaroundView = findViewById(R.id.workaround_view); - InsetsHelper.setUpAppBarWithScrollView(this, appBarLayout, scrollView, workaroundView); - ThemeHelper.enableScrollTint(this, tb, appBarLayout); + InsetsHelper.setUpAppBarWithScrollView(this, binding.appbarConvert, binding.scrollViewConvert, + binding.workaroundView); + ThemeHelper.enableScrollTint(this, binding.toolbarConvert, binding.appbarConvert); } @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index f40de0be3d..206ad33499 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -12,7 +12,6 @@ import android.os.Bundle; import android.util.SparseIntArray; import android.view.InputDevice; import android.view.KeyEvent; -import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; @@ -33,6 +32,9 @@ import androidx.preference.PreferenceManager; import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ActivityEmulationBinding; +import org.dolphinemu.dolphinemu.databinding.DialogInputAdjustBinding; +import org.dolphinemu.dolphinemu.databinding.DialogIrSensitivityBinding; import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting; import org.dolphinemu.dolphinemu.features.settings.model.IntSetting; import org.dolphinemu.dolphinemu.features.settings.model.Settings; @@ -62,7 +64,6 @@ import java.util.List; import static java.lang.annotation.RetentionPolicy.SOURCE; import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.slider.LabelFormatter; import com.google.android.material.slider.Slider; public final class EmulationActivity extends AppCompatActivity implements ThemeProvider @@ -338,7 +339,8 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP Rumble.initRumble(this); - setContentView(R.layout.activity_emulation); + ActivityEmulationBinding binding = ActivityEmulationBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); // Find or create the EmulationFragment mEmulationFragment = (EmulationFragment) getSupportFragmentManager() @@ -905,11 +907,10 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP private void adjustScale() { - LayoutInflater inflater = LayoutInflater.from(this); - View view = inflater.inflate(R.layout.dialog_input_adjust, null); + DialogInputAdjustBinding dialogBinding = DialogInputAdjustBinding.inflate(getLayoutInflater()); - final Slider scaleSlider = view.findViewById(R.id.input_scale_slider); - final TextView scaleValue = view.findViewById(R.id.input_scale_value); + final Slider scaleSlider = dialogBinding.inputScaleSlider; + final TextView scaleValue = dialogBinding.inputScaleValue; scaleSlider.setValueTo(150); scaleSlider.setValue(IntSetting.MAIN_CONTROL_SCALE.getInt(mSettings)); scaleSlider.setStepSize(1); @@ -918,8 +919,8 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP scaleValue.setText(((int) scaleSlider.getValue() + 50) + "%"); // alpha - final Slider sliderOpacity = view.findViewById(R.id.input_opacity_slider); - final TextView valueOpacity = view.findViewById(R.id.input_opacity_value); + final Slider sliderOpacity = dialogBinding.inputOpacitySlider; + final TextView valueOpacity = dialogBinding.inputOpacityValue; sliderOpacity.setValueTo(100); sliderOpacity.setValue(IntSetting.MAIN_CONTROL_OPACITY.getInt(mSettings)); sliderOpacity.setStepSize(1); @@ -927,10 +928,9 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP (slider, progress, fromUser) -> valueOpacity.setText(((int) progress) + "%")); valueOpacity.setText(((int) sliderOpacity.getValue()) + "%"); - new MaterialAlertDialogBuilder(this) .setTitle(R.string.emulation_control_adjustments) - .setView(view) + .setView(dialogBinding.getRoot()) .setPositiveButton(R.string.ok, (dialog, which) -> { IntSetting.MAIN_CONTROL_SCALE.setInt(mSettings, (int) scaleSlider.getValue()); @@ -1008,12 +1008,12 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP int ir_pitch = ini.getInt(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_PITCH, 20); - LayoutInflater inflater = LayoutInflater.from(this); - View view = inflater.inflate(R.layout.dialog_ir_sensitivity, null); + DialogIrSensitivityBinding dialogBinding = + DialogIrSensitivityBinding.inflate(getLayoutInflater()); - TextView text_slider_value_pitch = view.findViewById(R.id.text_ir_pitch); - TextView units = view.findViewById(R.id.text_ir_pitch_units); - Slider slider_pitch = view.findViewById(R.id.slider_pitch); + TextView text_slider_value_pitch = dialogBinding.textIrPitch; + TextView units = dialogBinding.textIrPitchUnits; + Slider slider_pitch = dialogBinding.sliderPitch; text_slider_value_pitch.setText(String.valueOf(ir_pitch)); units.setText(getString(R.string.pitch)); @@ -1026,9 +1026,9 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP int ir_yaw = ini.getInt(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_YAW, 25); - TextView text_slider_value_yaw = view.findViewById(R.id.text_ir_yaw); - TextView units_yaw = view.findViewById(R.id.text_ir_yaw_units); - Slider seekbar_yaw = view.findViewById(R.id.slider_width); + TextView text_slider_value_yaw = dialogBinding.textIrYaw; + TextView units_yaw = dialogBinding.textIrYawUnits; + Slider seekbar_yaw = dialogBinding.sliderYaw; text_slider_value_yaw.setText(String.valueOf(ir_yaw)); units_yaw.setText(getString(R.string.yaw)); @@ -1038,13 +1038,12 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP seekbar_yaw.addOnChangeListener((slider, progress, fromUser) -> text_slider_value_yaw.setText( String.valueOf((int) progress))); - int ir_vertical_offset = ini.getInt(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_VERTICAL_OFFSET, 10); - TextView text_slider_value_vertical_offset = view.findViewById(R.id.text_ir_vertical_offset); - TextView units_vertical_offset = view.findViewById(R.id.text_ir_vertical_offset_units); - Slider seekbar_vertical_offset = view.findViewById(R.id.slider_vertical_offset); + TextView text_slider_value_vertical_offset = dialogBinding.textIrVerticalOffset; + TextView units_vertical_offset = dialogBinding.textIrVerticalOffsetUnits; + Slider seekbar_vertical_offset = dialogBinding.sliderVerticalOffset; text_slider_value_vertical_offset.setText(String.valueOf(ir_vertical_offset)); units_vertical_offset.setText(getString(R.string.vertical_offset)); @@ -1057,7 +1056,7 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP new MaterialAlertDialogBuilder(this) .setTitle(getString(R.string.emulation_ir_sensitivity)) - .setView(view) + .setView(dialogBinding.getRoot()) .setPositiveButton(R.string.ok, (dialogInterface, i) -> { ini.setString(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_PITCH, diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.java index 9f6a211cd9..c40d4e2e57 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.java @@ -10,19 +10,15 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.view.View; -import android.widget.Button; -import android.widget.TextView; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.core.view.WindowCompat; -import androidx.core.widget.NestedScrollView; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ActivityUserDataBinding; import org.dolphinemu.dolphinemu.utils.DirectoryInitialization; import org.dolphinemu.dolphinemu.utils.InsetsHelper; import org.dolphinemu.dolphinemu.utils.Log; @@ -61,45 +57,36 @@ public class UserDataActivity extends AppCompatActivity super.onCreate(savedInstanceState); - setContentView(R.layout.activity_user_data); + ActivityUserDataBinding binding = ActivityUserDataBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); WindowCompat.setDecorFitsSystemWindows(getWindow(), false); - TextView textType = findViewById(R.id.text_type); - TextView textPath = findViewById(R.id.text_path); - TextView textAndroid11 = findViewById(R.id.text_android_11); - Button buttonOpenSystemFileManager = findViewById(R.id.button_open_system_file_manager); - Button buttonImportUserData = findViewById(R.id.button_import_user_data); - Button buttonExportUserData = findViewById(R.id.button_export_user_data); - boolean android_10 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q; boolean android_11 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R; boolean legacy = DirectoryInitialization.isUsingLegacyUserDirectory(); int user_data_new_location = android_10 ? R.string.user_data_new_location_android_10 : R.string.user_data_new_location; - textType.setText(legacy ? R.string.user_data_old_location : user_data_new_location); + binding.textType.setText(legacy ? R.string.user_data_old_location : user_data_new_location); - textPath.setText(DirectoryInitialization.getUserDirectory()); + binding.textPath.setText(DirectoryInitialization.getUserDirectory()); - textAndroid11.setVisibility(android_11 && !legacy ? View.VISIBLE : View.GONE); + binding.textAndroid11.setVisibility(android_11 && !legacy ? View.VISIBLE : View.GONE); - buttonOpenSystemFileManager.setVisibility(android_11 ? View.VISIBLE : View.GONE); - buttonOpenSystemFileManager.setOnClickListener(view -> openFileManager()); + binding.buttonOpenSystemFileManager.setVisibility(android_11 ? View.VISIBLE : View.GONE); + binding.buttonOpenSystemFileManager.setOnClickListener(view -> openFileManager()); - buttonImportUserData.setOnClickListener(view -> importUserData()); + binding.buttonImportUserData.setOnClickListener(view -> importUserData()); - buttonExportUserData.setOnClickListener(view -> exportUserData()); + binding.buttonExportUserData.setOnClickListener(view -> exportUserData()); - MaterialToolbar tb = findViewById(R.id.toolbar_user_data); - setSupportActionBar(tb); + setSupportActionBar(binding.toolbarUserData); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - AppBarLayout appBarLayout = findViewById(R.id.appbar_user_data); - NestedScrollView scrollView = findViewById(R.id.scroll_view_user_data); - View workaroundView = findViewById(R.id.workaround_view); - InsetsHelper.setUpAppBarWithScrollView(this, appBarLayout, scrollView, workaroundView); - ThemeHelper.enableScrollTint(this, tb, appBarLayout); + InsetsHelper.setUpAppBarWithScrollView(this, binding.appbarUserData, + binding.scrollViewUserData, binding.workaroundView); + ThemeHelper.enableScrollTint(this, binding.toolbarUserData, binding.appbarUserData); } @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java index 25d683cbac..21470269a9 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java @@ -3,7 +3,6 @@ package org.dolphinemu.dolphinemu.adapters; import android.content.Context; -import android.graphics.Rect; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -14,16 +13,16 @@ import androidx.recyclerview.widget.RecyclerView; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.activities.EmulationActivity; +import org.dolphinemu.dolphinemu.databinding.CardGameBinding; import org.dolphinemu.dolphinemu.dialogs.GamePropertiesDialog; import org.dolphinemu.dolphinemu.model.GameFile; import org.dolphinemu.dolphinemu.services.GameFileCacheManager; import org.dolphinemu.dolphinemu.utils.GlideUtils; -import org.dolphinemu.dolphinemu.viewholders.GameViewHolder; import java.util.ArrayList; import java.util.List; -public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> implements +public final class GameAdapter extends RecyclerView.Adapter<GameAdapter.GameViewHolder> implements View.OnClickListener, View.OnLongClickListener { @@ -45,18 +44,17 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl * @param viewType Not used here, but useful when more than one type of child will be used in the RecyclerView. * @return The created ViewHolder with references to all the child view's members. */ + @NonNull @Override public GameViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - // Create a new view. - View gameCard = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.card_game, parent, false); + CardGameBinding binding = CardGameBinding.inflate(LayoutInflater.from(parent.getContext())); - gameCard.setOnClickListener(this); - gameCard.setOnLongClickListener(this); + binding.getRoot().setOnClickListener(this); + binding.getRoot().setOnLongClickListener(this); // Use that view to create a ViewHolder. - return new GameViewHolder(gameCard); + return new GameViewHolder(binding); } /** @@ -72,21 +70,34 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl { Context context = holder.itemView.getContext(); GameFile gameFile = mGameFiles.get(position); - GlideUtils.loadGameCover(holder, holder.imageScreenshot, gameFile); + GlideUtils.loadGameCover(holder, holder.binding.imageGameScreen, gameFile); if (GameFileCacheManager.findSecondDisc(gameFile) != null) { - holder.textGameCaption + holder.binding.textGameCaption .setText(context.getString(R.string.disc_number, gameFile.getDiscNumber() + 1)); } else { - holder.textGameCaption.setText(gameFile.getCompany()); + holder.binding.textGameCaption.setText(gameFile.getCompany()); } holder.gameFile = gameFile; } + public static class GameViewHolder extends RecyclerView.ViewHolder + { + public GameFile gameFile; + public CardGameBinding binding; + + public GameViewHolder(@NonNull CardGameBinding binding) + { + super(binding.getRoot()); + binding.getRoot().setTag(this); + this.binding = binding; + } + } + /** * Called by the LayoutManager to find out how much data we have. * diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java index f049fd97a8..dec25dbf2a 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java @@ -5,16 +5,15 @@ package org.dolphinemu.dolphinemu.dialogs; import android.app.Dialog; import android.os.Bundle; import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.fragment.app.DialogFragment; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.DialogGameDetailsBinding; import org.dolphinemu.dolphinemu.model.GameFile; import org.dolphinemu.dolphinemu.services.GameFileCacheManager; import org.dolphinemu.dolphinemu.utils.GlideUtils; @@ -34,90 +33,72 @@ public final class GameDetailsDialog extends DialogFragment return fragment; } + @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { GameFile gameFile = GameFileCacheManager.addOrGet(getArguments().getString(ARG_GAME_PATH)); - ViewGroup contents = (ViewGroup) getActivity().getLayoutInflater() - .inflate(R.layout.dialog_game_details, null); - - ImageView banner = contents.findViewById(R.id.banner); - - TextView textTitle = contents.findViewById(R.id.text_game_title); - TextView textDescription = contents.findViewById(R.id.text_description); - - TextView textCountry = contents.findViewById(R.id.text_country); - TextView textCompany = contents.findViewById(R.id.text_company); - TextView textGameId = contents.findViewById(R.id.text_game_id); - TextView textRevision = contents.findViewById(R.id.text_revision); - - TextView textFileFormat = contents.findViewById(R.id.text_file_format); - TextView textCompression = contents.findViewById(R.id.text_compression); - TextView textBlockSize = contents.findViewById(R.id.text_block_size); - - TextView labelFileFormat = contents.findViewById(R.id.label_file_format); - TextView labelCompression = contents.findViewById(R.id.label_compression); - TextView labelBlockSize = contents.findViewById(R.id.label_block_size); + DialogGameDetailsBinding binding = DialogGameDetailsBinding.inflate(getLayoutInflater()); String country = getResources().getStringArray(R.array.countryNames)[gameFile.getCountry()]; String description = gameFile.getDescription(); String fileSize = NativeLibrary.FormatSize(gameFile.getFileSize(), 2); - textTitle.setText(gameFile.getTitle()); - textDescription.setText(gameFile.getDescription()); + binding.textGameTitle.setText(gameFile.getTitle()); + binding.textDescription.setText(gameFile.getDescription()); if (description.isEmpty()) { - textDescription.setVisibility(View.GONE); + binding.textDescription.setVisibility(View.GONE); } - textCountry.setText(country); - textCompany.setText(gameFile.getCompany()); - textGameId.setText(gameFile.getGameId()); - textRevision.setText(String.valueOf(gameFile.getRevision())); + binding.textCountry.setText(country); + binding.textCompany.setText(gameFile.getCompany()); + binding.textGameId.setText(gameFile.getGameId()); + binding.textRevision.setText(String.valueOf(gameFile.getRevision())); if (!gameFile.shouldShowFileFormatDetails()) { - labelFileFormat.setText(R.string.game_details_file_size); - textFileFormat.setText(fileSize); + binding.labelFileFormat.setText(R.string.game_details_file_size); + binding.textFileFormat.setText(fileSize); - labelCompression.setVisibility(View.GONE); - textCompression.setVisibility(View.GONE); - labelBlockSize.setVisibility(View.GONE); - textBlockSize.setVisibility(View.GONE); + binding.labelCompression.setVisibility(View.GONE); + binding.textCompression.setVisibility(View.GONE); + binding.labelBlockSize.setVisibility(View.GONE); + binding.textBlockSize.setVisibility(View.GONE); } else { long blockSize = gameFile.getBlockSize(); String compression = gameFile.getCompressionMethod(); - textFileFormat.setText(getResources().getString(R.string.game_details_size_and_format, + binding.textFileFormat.setText(getResources().getString(R.string.game_details_size_and_format, gameFile.getFileFormatName(), fileSize)); if (compression.isEmpty()) { - textCompression.setText(R.string.game_details_no_compression); + binding.textCompression.setText(R.string.game_details_no_compression); } else { - textCompression.setText(gameFile.getCompressionMethod()); + binding.textCompression.setText(gameFile.getCompressionMethod()); } if (blockSize > 0) { - textBlockSize.setText(NativeLibrary.FormatSize(blockSize, 0)); + binding.textBlockSize.setText(NativeLibrary.FormatSize(blockSize, 0)); } else { - labelBlockSize.setVisibility(View.GONE); - textBlockSize.setVisibility(View.GONE); + binding.labelBlockSize.setVisibility(View.GONE); + binding.textBlockSize.setVisibility(View.GONE); } } - GlideUtils.loadGameBanner(banner, gameFile); + GlideUtils.loadGameBanner(binding.banner, gameFile); return new MaterialAlertDialogBuilder(requireActivity()) - .setView(contents) + .setView(binding.getRoot()) .create(); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/ActionViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/ActionViewHolder.java index 3e99384fdd..fd6617cd21 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/ActionViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/ActionViewHolder.java @@ -9,6 +9,7 @@ import androidx.annotation.NonNull; import androidx.lifecycle.ViewModelProvider; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemSubmenuBinding; import org.dolphinemu.dolphinemu.features.cheats.model.ARCheat; import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel; import org.dolphinemu.dolphinemu.features.cheats.model.GeckoCheat; @@ -23,13 +24,13 @@ public class ActionViewHolder extends CheatItemViewHolder implements View.OnClic private int mString; private int mPosition; - public ActionViewHolder(@NonNull View itemView) + public ActionViewHolder(@NonNull ListItemSubmenuBinding binding) { - super(itemView); + super(binding.getRoot()); - mName = itemView.findViewById(R.id.text_setting_name); + mName = binding.textSettingName; - itemView.setOnClickListener(this); + binding.getRoot().setOnClickListener(this); } public void bind(CheatsActivity activity, CheatItem item, int position) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java index f08b04abec..9e118e3932 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java @@ -6,8 +6,6 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ScrollView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -15,78 +13,57 @@ import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.textfield.TextInputEditText; -import com.google.android.material.textfield.TextInputLayout; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.FragmentCheatDetailsBinding; import org.dolphinemu.dolphinemu.features.cheats.model.Cheat; import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel; public class CheatDetailsFragment extends Fragment { - private View mRoot; - private ScrollView mScrollView; - private TextInputLayout mEditNameLayout; - private TextInputEditText mEditName; - private TextInputLayout mEditCreatorLayout; - private TextInputEditText mEditCreator; - private TextInputLayout mEditNotesLayout; - private TextInputEditText mEditNotes; - private TextInputLayout mEditCodeLayout; - private TextInputEditText mEditCode; - private Button mButtonDelete; - private Button mButtonEdit; - private Button mButtonCancel; - private Button mButtonOk; - private CheatsViewModel mViewModel; private Cheat mCheat; + private FragmentCheatDetailsBinding mBinding; + @Nullable @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_cheat_details, container, false); + mBinding = FragmentCheatDetailsBinding.inflate(inflater, container, false); + return mBinding.getRoot(); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - mRoot = view.findViewById(R.id.root); - mScrollView = view.findViewById(R.id.scroll_view); - mEditNameLayout = view.findViewById(R.id.edit_name); - mEditName = view.findViewById(R.id.edit_name_input); - mEditCreatorLayout = view.findViewById(R.id.edit_creator); - mEditCreator = view.findViewById(R.id.edit_creator_input); - mEditNotesLayout = view.findViewById(R.id.edit_notes); - mEditNotes = view.findViewById(R.id.edit_notes_input); - mEditCodeLayout = view.findViewById(R.id.edit_code); - mEditCode = view.findViewById(R.id.edit_code_input); - mButtonDelete = view.findViewById(R.id.button_delete); - mButtonEdit = view.findViewById(R.id.button_edit); - mButtonCancel = view.findViewById(R.id.button_cancel); - mButtonOk = view.findViewById(R.id.button_ok); - CheatsActivity activity = (CheatsActivity) requireActivity(); mViewModel = new ViewModelProvider(activity).get(CheatsViewModel.class); mViewModel.getSelectedCheat().observe(getViewLifecycleOwner(), this::onSelectedCheatUpdated); mViewModel.getIsEditing().observe(getViewLifecycleOwner(), this::onIsEditingUpdated); - mButtonDelete.setOnClickListener(this::onDeleteClicked); - mButtonEdit.setOnClickListener(this::onEditClicked); - mButtonCancel.setOnClickListener(this::onCancelClicked); - mButtonOk.setOnClickListener(this::onOkClicked); + mBinding.buttonDelete.setOnClickListener(this::onDeleteClicked); + mBinding.buttonEdit.setOnClickListener(this::onEditClicked); + mBinding.buttonCancel.setOnClickListener(this::onCancelClicked); + mBinding.buttonOk.setOnClickListener(this::onOkClicked); CheatsActivity.setOnFocusChangeListenerRecursively(view, (v, hasFocus) -> activity.onDetailsViewFocusChange(hasFocus)); } + @Override + public void onDestroyView() + { + super.onDestroyView(); + mBinding = null; + } + private void clearEditErrors() { - mEditNameLayout.setError(null); - mEditCodeLayout.setError(null); + mBinding.editName.setError(null); + mBinding.editCode.setError(null); } private void onDeleteClicked(View view) @@ -101,22 +78,24 @@ public class CheatDetailsFragment extends Fragment private void onEditClicked(View view) { mViewModel.setIsEditing(true); - mButtonOk.requestFocus(); + mBinding.buttonOk.requestFocus(); } private void onCancelClicked(View view) { mViewModel.setIsEditing(false); onSelectedCheatUpdated(mCheat); - mButtonDelete.requestFocus(); + mBinding.buttonDelete.requestFocus(); } private void onOkClicked(View view) { clearEditErrors(); - int result = mCheat.trySet(mEditName.getText().toString(), mEditCreator.getText().toString(), - mEditNotes.getText().toString(), mEditCode.getText().toString()); + int result = mCheat.trySet(mBinding.editNameInput.getText().toString(), + mBinding.editCreatorInput.getText().toString(), + mBinding.editNotesInput.getText().toString(), + mBinding.editCodeInput.getText().toString()); switch (result) { @@ -131,23 +110,23 @@ public class CheatDetailsFragment extends Fragment mViewModel.notifySelectedCheatChanged(); mViewModel.setIsEditing(false); } - mButtonEdit.requestFocus(); + mBinding.buttonEdit.requestFocus(); break; case Cheat.TRY_SET_FAIL_NO_NAME: - mEditNameLayout.setError(getString(R.string.cheats_error_no_name)); - mScrollView.smoothScrollTo(0, mEditName.getTop()); + mBinding.editName.setError(getString(R.string.cheats_error_no_name)); + mBinding.scrollView.smoothScrollTo(0, mBinding.editNameInput.getTop()); break; case Cheat.TRY_SET_FAIL_NO_CODE_LINES: - mEditCodeLayout.setError(getString(R.string.cheats_error_no_code_lines)); - mScrollView.smoothScrollTo(0, mEditCode.getBottom()); + mBinding.editCode.setError(getString(R.string.cheats_error_no_code_lines)); + mBinding.scrollView.smoothScrollTo(0, mBinding.editCodeInput.getBottom()); break; case Cheat.TRY_SET_FAIL_CODE_MIXED_ENCRYPTION: - mEditCodeLayout.setError(getString(R.string.cheats_error_mixed_encryption)); - mScrollView.smoothScrollTo(0, mEditCode.getBottom()); + mBinding.editCode.setError(getString(R.string.cheats_error_mixed_encryption)); + mBinding.scrollView.smoothScrollTo(0, mBinding.editCodeInput.getBottom()); break; default: - mEditCodeLayout.setError(getString(R.string.cheats_error_on_line, result)); - mScrollView.smoothScrollTo(0, mEditCode.getBottom()); + mBinding.editCode.setError(getString(R.string.cheats_error_on_line, result)); + mBinding.scrollView.smoothScrollTo(0, mBinding.editCodeInput.getBottom()); break; } } @@ -156,18 +135,18 @@ public class CheatDetailsFragment extends Fragment { clearEditErrors(); - mRoot.setVisibility(cheat == null ? View.GONE : View.VISIBLE); + mBinding.root.setVisibility(cheat == null ? View.GONE : View.VISIBLE); int creatorVisibility = cheat != null && cheat.supportsCreator() ? View.VISIBLE : View.GONE; int notesVisibility = cheat != null && cheat.supportsNotes() ? View.VISIBLE : View.GONE; int codeVisibility = cheat != null && cheat.supportsCode() ? View.VISIBLE : View.GONE; - mEditCreatorLayout.setVisibility(creatorVisibility); - mEditNotesLayout.setVisibility(notesVisibility); - mEditCodeLayout.setVisibility(codeVisibility); + mBinding.editCreator.setVisibility(creatorVisibility); + mBinding.editNotes.setVisibility(notesVisibility); + mBinding.editCode.setVisibility(codeVisibility); boolean userDefined = cheat != null && cheat.getUserDefined(); - mButtonDelete.setEnabled(userDefined); - mButtonEdit.setEnabled(userDefined); + mBinding.buttonDelete.setEnabled(userDefined); + mBinding.buttonEdit.setEnabled(userDefined); // If the fragment was recreated while editing a cheat, it's vital that we // don't repopulate the fields, otherwise the user's changes will be lost @@ -175,10 +154,10 @@ public class CheatDetailsFragment extends Fragment if (!isEditing && cheat != null) { - mEditName.setText(cheat.getName()); - mEditCreator.setText(cheat.getCreator()); - mEditNotes.setText(cheat.getNotes()); - mEditCode.setText(cheat.getCode()); + mBinding.editNameInput.setText(cheat.getName()); + mBinding.editCreatorInput.setText(cheat.getCreator()); + mBinding.editNotesInput.setText(cheat.getNotes()); + mBinding.editCodeInput.setText(cheat.getCode()); } mCheat = cheat; @@ -186,14 +165,14 @@ public class CheatDetailsFragment extends Fragment private void onIsEditingUpdated(boolean isEditing) { - mEditName.setEnabled(isEditing); - mEditCreator.setEnabled(isEditing); - mEditNotes.setEnabled(isEditing); - mEditCode.setEnabled(isEditing); - - mButtonDelete.setVisibility(isEditing ? View.GONE : View.VISIBLE); - mButtonEdit.setVisibility(isEditing ? View.GONE : View.VISIBLE); - mButtonCancel.setVisibility(isEditing ? View.VISIBLE : View.GONE); - mButtonOk.setVisibility(isEditing ? View.VISIBLE : View.GONE); + mBinding.editNameInput.setEnabled(isEditing); + mBinding.editCreatorInput.setEnabled(isEditing); + mBinding.editNotesInput.setEnabled(isEditing); + mBinding.editCodeInput.setEnabled(isEditing); + + mBinding.buttonDelete.setVisibility(isEditing ? View.GONE : View.VISIBLE); + mBinding.buttonEdit.setVisibility(isEditing ? View.GONE : View.VISIBLE); + mBinding.buttonCancel.setVisibility(isEditing ? View.VISIBLE : View.GONE); + mBinding.buttonOk.setVisibility(isEditing ? View.VISIBLE : View.GONE); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatListFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatListFragment.java index 60c20590d9..6f1d295dde 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatListFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatListFragment.java @@ -12,40 +12,47 @@ import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.divider.MaterialDividerItemDecoration; -import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.FragmentCheatListBinding; import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel; import org.dolphinemu.dolphinemu.utils.InsetsHelper; public class CheatListFragment extends Fragment { + private FragmentCheatListBinding mBinding; + @Nullable @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_cheat_list, container, false); + mBinding = FragmentCheatListBinding.inflate(inflater, container, false); + return mBinding.getRoot(); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - RecyclerView recyclerView = view.findViewById(R.id.cheat_list); - CheatsActivity activity = (CheatsActivity) requireActivity(); CheatsViewModel viewModel = new ViewModelProvider(activity).get(CheatsViewModel.class); - recyclerView.setAdapter(new CheatsAdapter(activity, viewModel)); - recyclerView.setLayoutManager(new LinearLayoutManager(activity)); + mBinding.cheatList.setAdapter(new CheatsAdapter(activity, viewModel)); + mBinding.cheatList.setLayoutManager(new LinearLayoutManager(activity)); MaterialDividerItemDecoration divider = new MaterialDividerItemDecoration(requireActivity(), LinearLayoutManager.VERTICAL); divider.setLastItemDecorated(false); - recyclerView.addItemDecoration(divider); + mBinding.cheatList.addItemDecoration(divider); + + InsetsHelper.setUpList(getContext(), mBinding.cheatList); + } - InsetsHelper.setUpList(getContext(), recyclerView); + @Override + public void onDestroyView() + { + super.onDestroyView(); + mBinding = null; } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatViewHolder.java index a37abd145a..806b960b58 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatViewHolder.java @@ -10,43 +10,38 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.lifecycle.ViewModelProvider; -import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemCheatBinding; import org.dolphinemu.dolphinemu.features.cheats.model.Cheat; import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel; public class CheatViewHolder extends CheatItemViewHolder implements View.OnClickListener, CompoundButton.OnCheckedChangeListener { - private final View mRoot; - private final TextView mName; - private final CheckBox mCheckbox; + private final ListItemCheatBinding mBinding; private CheatsViewModel mViewModel; private Cheat mCheat; private int mPosition; - public CheatViewHolder(@NonNull View itemView) + public CheatViewHolder(@NonNull ListItemCheatBinding binding) { - super(itemView); - - mRoot = itemView.findViewById(R.id.root); - mName = itemView.findViewById(R.id.text_name); - mCheckbox = itemView.findViewById(R.id.checkbox); + super(binding.getRoot()); + mBinding = binding; } public void bind(CheatsActivity activity, CheatItem item, int position) { - mCheckbox.setOnCheckedChangeListener(null); + mBinding.checkbox.setOnCheckedChangeListener(null); mViewModel = new ViewModelProvider(activity).get(CheatsViewModel.class); mCheat = item.getCheat(); mPosition = position; - mName.setText(mCheat.getName()); - mCheckbox.setChecked(mCheat.getEnabled()); + mBinding.textName.setText(mCheat.getName()); + mBinding.checkbox.setChecked(mCheat.getEnabled()); - mRoot.setOnClickListener(this); - mCheckbox.setOnCheckedChangeListener(this); + mBinding.root.setOnClickListener(this); + mBinding.checkbox.setOnCheckedChangeListener(this); } public void onClick(View root) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsActivity.java index 189db827be..0827c3197e 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsActivity.java @@ -19,12 +19,11 @@ import androidx.core.view.WindowCompat; import androidx.lifecycle.ViewModelProvider; import androidx.slidingpanelayout.widget.SlidingPaneLayout; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.color.MaterialColors; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ActivityCheatsBinding; import org.dolphinemu.dolphinemu.features.cheats.model.Cheat; import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel; import org.dolphinemu.dolphinemu.features.cheats.model.GeckoCheat; @@ -48,13 +47,11 @@ public class CheatsActivity extends AppCompatActivity private boolean mIsWii; private CheatsViewModel mViewModel; - private SlidingPaneLayout mSlidingPaneLayout; - private View mCheatList; - private View mCheatDetails; - private View mCheatListLastFocus; private View mCheatDetailsLastFocus; + private ActivityCheatsBinding mBinding; + public static void launch(Context context, String gameId, String gameTdbId, int revision, boolean isWii) { @@ -86,38 +83,34 @@ public class CheatsActivity extends AppCompatActivity mViewModel = new ViewModelProvider(this).get(CheatsViewModel.class); mViewModel.load(mGameId, mRevision); - setContentView(R.layout.activity_cheats); + mBinding = ActivityCheatsBinding.inflate(getLayoutInflater()); + setContentView(mBinding.getRoot()); WindowCompat.setDecorFitsSystemWindows(getWindow(), false); - mSlidingPaneLayout = findViewById(R.id.sliding_pane_layout); - mCheatList = findViewById(R.id.cheat_list); - mCheatDetails = findViewById(R.id.cheat_details); - - mCheatListLastFocus = mCheatList; - mCheatDetailsLastFocus = mCheatDetails; + mCheatListLastFocus = mBinding.cheatList; + mCheatDetailsLastFocus = mBinding.cheatDetails; - mSlidingPaneLayout.addPanelSlideListener(this); + mBinding.slidingPaneLayout.addPanelSlideListener(this); getOnBackPressedDispatcher().addCallback(this, - new TwoPaneOnBackPressedCallback(mSlidingPaneLayout)); + new TwoPaneOnBackPressedCallback(mBinding.slidingPaneLayout)); mViewModel.getSelectedCheat().observe(this, this::onSelectedCheatChanged); onSelectedCheatChanged(mViewModel.getSelectedCheat().getValue()); mViewModel.getOpenDetailsViewEvent().observe(this, this::openDetailsView); - MaterialToolbar tb = findViewById(R.id.toolbar_cheats); - setSupportActionBar(tb); + setSupportActionBar(mBinding.toolbarCheats); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - View workaroundView = findViewById(R.id.workaround_view); - AppBarLayout appBarLayout = findViewById(R.id.appbar_cheats); - InsetsHelper.setUpCheatsLayout(this, appBarLayout, mSlidingPaneLayout, mCheatDetails, - workaroundView); + InsetsHelper.setUpCheatsLayout(this, mBinding.appbarCheats, mBinding.slidingPaneLayout, + mBinding.cheatDetails, + mBinding.workaroundView); - @ColorInt int color = MaterialColors.getColor(tb, R.attr.colorSurfaceVariant); - tb.setBackgroundColor(color); + @ColorInt int color = + MaterialColors.getColor(mBinding.toolbarCheats, R.attr.colorSurfaceVariant); + mBinding.toolbarCheats.setBackgroundColor(color); ThemeHelper.setStatusBarColor(this, color); } @@ -161,10 +154,10 @@ public class CheatsActivity extends AppCompatActivity { boolean cheatSelected = selectedCheat != null; - if (!cheatSelected && mSlidingPaneLayout.isOpen()) - mSlidingPaneLayout.close(); + if (!cheatSelected && mBinding.slidingPaneLayout.isOpen()) + mBinding.slidingPaneLayout.close(); - mSlidingPaneLayout.setLockMode(cheatSelected ? + mBinding.slidingPaneLayout.setLockMode(cheatSelected ? SlidingPaneLayout.LOCK_MODE_UNLOCKED : SlidingPaneLayout.LOCK_MODE_LOCKED_CLOSED); } @@ -172,11 +165,11 @@ public class CheatsActivity extends AppCompatActivity { if (hasFocus) { - mCheatListLastFocus = mCheatList.findFocus(); + mCheatListLastFocus = mBinding.cheatList.findFocus(); if (mCheatListLastFocus == null) throw new NullPointerException(); - mSlidingPaneLayout.close(); + mBinding.slidingPaneLayout.close(); } } @@ -184,11 +177,11 @@ public class CheatsActivity extends AppCompatActivity { if (hasFocus) { - mCheatDetailsLastFocus = mCheatDetails.findFocus(); + mCheatDetailsLastFocus = mBinding.cheatDetails.findFocus(); if (mCheatDetailsLastFocus == null) throw new NullPointerException(); - mSlidingPaneLayout.open(); + mBinding.slidingPaneLayout.open(); } } @@ -202,7 +195,7 @@ public class CheatsActivity extends AppCompatActivity private void openDetailsView(boolean open) { if (open) - mSlidingPaneLayout.open(); + mBinding.slidingPaneLayout.open(); } public Settings loadGameSpecificSettings() diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java index e5be47a3f1..3335795c75 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java @@ -10,6 +10,9 @@ import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemCheatBinding; +import org.dolphinemu.dolphinemu.databinding.ListItemHeaderBinding; +import org.dolphinemu.dolphinemu.databinding.ListItemSubmenuBinding; import org.dolphinemu.dolphinemu.features.cheats.model.ARCheat; import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel; import org.dolphinemu.dolphinemu.features.cheats.model.GeckoCheat; @@ -66,17 +69,17 @@ public class CheatsAdapter extends RecyclerView.Adapter<CheatItemViewHolder> switch (viewType) { case CheatItem.TYPE_CHEAT: - View cheatView = inflater.inflate(R.layout.list_item_cheat, parent, false); - addViewListeners(cheatView); - return new CheatViewHolder(cheatView); + ListItemCheatBinding listItemCheatBinding = ListItemCheatBinding.inflate(inflater); + addViewListeners(listItemCheatBinding.getRoot()); + return new CheatViewHolder(listItemCheatBinding); case CheatItem.TYPE_HEADER: - View headerView = inflater.inflate(R.layout.list_item_header, parent, false); - addViewListeners(headerView); - return new HeaderViewHolder(headerView); + ListItemHeaderBinding listItemHeaderBinding = ListItemHeaderBinding.inflate(inflater); + addViewListeners(listItemHeaderBinding.getRoot()); + return new HeaderViewHolder(listItemHeaderBinding); case CheatItem.TYPE_ACTION: - View actionView = inflater.inflate(R.layout.list_item_submenu, parent, false); - addViewListeners(actionView); - return new ActionViewHolder(actionView); + ListItemSubmenuBinding listItemSubmenuBinding = ListItemSubmenuBinding.inflate(inflater); + addViewListeners(listItemSubmenuBinding.getRoot()); + return new ActionViewHolder(listItemSubmenuBinding); default: throw new UnsupportedOperationException(); } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/HeaderViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/HeaderViewHolder.java index c48ec500ff..8f347d363e 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/HeaderViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/HeaderViewHolder.java @@ -8,16 +8,17 @@ import android.widget.TextView; import androidx.annotation.NonNull; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemHeaderBinding; public class HeaderViewHolder extends CheatItemViewHolder { private TextView mHeaderName; - public HeaderViewHolder(@NonNull View itemView) + public HeaderViewHolder(@NonNull ListItemHeaderBinding binding) { - super(itemView); + super(binding.getRoot()); - mHeaderName = itemView.findViewById(R.id.text_header_name); + mHeaderName = binding.textHeaderName; } public void bind(CheatsActivity activity, CheatItem item, int position) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/SettingDisabledWarningFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/SettingDisabledWarningFragment.java index c239c5c9af..7e703f3fd1 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/SettingDisabledWarningFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/SettingDisabledWarningFragment.java @@ -6,14 +6,12 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; -import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.FragmentCheatWarningBinding; import org.dolphinemu.dolphinemu.features.settings.model.AbstractBooleanSetting; import org.dolphinemu.dolphinemu.features.settings.model.Settings; import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag; @@ -28,6 +26,8 @@ public abstract class SettingDisabledWarningFragment extends Fragment private final MenuTag mSettingShortcut; private final int mText; + private FragmentCheatWarningBinding mBinding; + public SettingDisabledWarningFragment(AbstractBooleanSetting setting, MenuTag settingShortcut, int text) { @@ -38,10 +38,11 @@ public abstract class SettingDisabledWarningFragment extends Fragment @Nullable @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_cheat_warning, container, false); + mBinding = FragmentCheatWarningBinding.inflate(inflater, container, false); + return mBinding.getRoot(); } @Override @@ -49,11 +50,8 @@ public abstract class SettingDisabledWarningFragment extends Fragment { mView = view; - TextView textView = view.findViewById(R.id.text_warning); - textView.setText(mText); - - Button settingsButton = view.findViewById(R.id.button_settings); - settingsButton.setOnClickListener(this); + mBinding.textWarning.setText(mText); + mBinding.buttonSettings.setOnClickListener(this); CheatsActivity activity = (CheatsActivity) requireActivity(); CheatsActivity.setOnFocusChangeListenerRecursively(view, @@ -73,6 +71,13 @@ public abstract class SettingDisabledWarningFragment extends Fragment } } + @Override + public void onDestroyView() + { + super.onDestroyView(); + mBinding = null; + } + public void onClick(View view) { SettingsActivity.launch(requireContext(), mSettingShortcut); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionAdapter.java index 92d933b3d6..68c209cc0c 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionAdapter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionAdapter.java @@ -9,7 +9,7 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; -import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemRiivolutionBinding; import org.dolphinemu.dolphinemu.features.riivolution.model.RiivolutionPatches; import java.util.ArrayList; @@ -48,8 +48,8 @@ public class RiivolutionAdapter extends RecyclerView.Adapter<RiivolutionViewHold public RiivolutionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); - return new RiivolutionViewHolder( - inflater.inflate(R.layout.list_item_riivolution, parent, false)); + ListItemRiivolutionBinding binding = ListItemRiivolutionBinding.inflate(inflater); + return new RiivolutionViewHolder(binding.getRoot(), binding); } @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionBootActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionBootActivity.java index 4186de21b8..88aa8228ed 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionBootActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionBootActivity.java @@ -5,22 +5,14 @@ package org.dolphinemu.dolphinemu.features.riivolution.ui; import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.view.View; -import android.widget.Button; -import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import androidx.core.view.WindowCompat; -import androidx.core.widget.NestedScrollView; import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; -import com.google.android.material.appbar.MaterialToolbar; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.activities.EmulationActivity; +import org.dolphinemu.dolphinemu.databinding.ActivityRiivolutionBootBinding; import org.dolphinemu.dolphinemu.features.riivolution.model.RiivolutionPatches; import org.dolphinemu.dolphinemu.features.settings.model.StringSetting; import org.dolphinemu.dolphinemu.utils.DirectoryInitialization; @@ -36,6 +28,8 @@ public class RiivolutionBootActivity extends AppCompatActivity private RiivolutionPatches mPatches; + private ActivityRiivolutionBootBinding mBinding; + public static void launch(Context context, String gamePath, String gameId, int revision, int discNumber) { @@ -54,7 +48,8 @@ public class RiivolutionBootActivity extends AppCompatActivity super.onCreate(savedInstanceState); - setContentView(R.layout.activity_riivolution_boot); + mBinding = ActivityRiivolutionBootBinding.inflate(getLayoutInflater()); + setContentView(mBinding.getRoot()); WindowCompat.setDecorFitsSystemWindows(getWindow(), false); @@ -69,11 +64,9 @@ public class RiivolutionBootActivity extends AppCompatActivity if (loadPath.isEmpty()) loadPath = DirectoryInitialization.getUserDirectory() + "/Load"; - TextView textSdRoot = findViewById(R.id.text_sd_root); - textSdRoot.setText(getString(R.string.riivolution_sd_root, loadPath + "/Riivolution")); + mBinding.textSdRoot.setText(getString(R.string.riivolution_sd_root, loadPath + "/Riivolution")); - Button buttonStart = findViewById(R.id.button_start); - buttonStart.setOnClickListener((v) -> + mBinding.buttonStart.setOnClickListener((v) -> { if (mPatches != null) mPatches.saveConfig(); @@ -88,17 +81,13 @@ public class RiivolutionBootActivity extends AppCompatActivity runOnUiThread(() -> populateList(patches)); }).start(); - MaterialToolbar tb = findViewById(R.id.toolbar_riivolution); - CollapsingToolbarLayout ctb = findViewById(R.id.toolbar_riivolution_layout); - ctb.setTitle(getString(R.string.riivolution_riivolution)); - setSupportActionBar(tb); + mBinding.toolbarRiivolutionLayout.setTitle(getString(R.string.riivolution_riivolution)); + setSupportActionBar(mBinding.toolbarRiivolution); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - AppBarLayout appBarLayout = findViewById(R.id.appbar_riivolution); - NestedScrollView scrollView = findViewById(R.id.scroll_view_riivolution); - View workaroundView = findViewById(R.id.workaround_view); - InsetsHelper.setUpAppBarWithScrollView(this, appBarLayout, scrollView, workaroundView); - ThemeHelper.enableScrollTint(this, tb, appBarLayout); + InsetsHelper.setUpAppBarWithScrollView(this, mBinding.appbarRiivolution, + mBinding.scrollViewRiivolution, mBinding.workaroundView); + ThemeHelper.enableScrollTint(this, mBinding.toolbarRiivolution, mBinding.appbarRiivolution); } @Override @@ -121,9 +110,7 @@ public class RiivolutionBootActivity extends AppCompatActivity { mPatches = patches; - RecyclerView recyclerView = findViewById(R.id.recycler_view); - - recyclerView.setAdapter(new RiivolutionAdapter(this, patches)); - recyclerView.setLayoutManager(new LinearLayoutManager(this)); + mBinding.recyclerView.setAdapter(new RiivolutionAdapter(this, patches)); + mBinding.recyclerView.setLayoutManager(new LinearLayoutManager(this)); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionViewHolder.java index 8cd8a21c59..4a8c4f383f 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionViewHolder.java @@ -6,60 +6,53 @@ import android.content.Context; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; -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.databinding.ListItemRiivolutionBinding; import org.dolphinemu.dolphinemu.features.riivolution.model.RiivolutionPatches; public class RiivolutionViewHolder extends RecyclerView.ViewHolder implements AdapterView.OnItemClickListener { - private final TextView mTextView; - private final TextInputLayout mChoiceLayout; - private final MaterialAutoCompleteTextView mChoiceDropdown; + private final ListItemRiivolutionBinding mBinding; + private RiivolutionPatches mPatches; private RiivolutionItem mItem; - public RiivolutionViewHolder(@NonNull View itemView) + public RiivolutionViewHolder(@NonNull View itemView, ListItemRiivolutionBinding binding) { super(itemView); - - mTextView = itemView.findViewById(R.id.text_name); - mChoiceLayout = itemView.findViewById(R.id.layout_choice); - mChoiceDropdown = itemView.findViewById(R.id.dropdown_choice); + mBinding = binding; } 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); + mBinding.dropdownChoice.setSaveEnabled(false); String text; if (item.mOptionIndex != -1) { - mTextView.setVisibility(View.GONE); + mBinding.textName.setVisibility(View.GONE); text = patches.getOptionName(item.mDiscIndex, item.mSectionIndex, item.mOptionIndex); - mChoiceLayout.setHint(text); + mBinding.layoutChoice.setHint(text); } else if (item.mSectionIndex != -1) { - mTextView.setTextAppearance(context, R.style.TextAppearance_AppCompat_Medium); - mChoiceLayout.setVisibility(View.GONE); + mBinding.textName.setTextAppearance(context, R.style.TextAppearance_AppCompat_Medium); + mBinding.layoutChoice.setVisibility(View.GONE); text = patches.getSectionName(item.mDiscIndex, item.mSectionIndex); } else { - mChoiceLayout.setVisibility(View.GONE); + mBinding.layoutChoice.setVisibility(View.GONE); text = patches.getDiscName(item.mDiscIndex); } - mTextView.setText(text); + mBinding.textName.setText(text); if (item.mOptionIndex != -1) { @@ -78,11 +71,11 @@ public class RiivolutionViewHolder extends RecyclerView.ViewHolder i)); } - mChoiceDropdown.setAdapter(adapter); - mChoiceDropdown.setText(adapter.getItem( + mBinding.dropdownChoice.setAdapter(adapter); + mBinding.dropdownChoice.setText(adapter.getItem( patches.getSelectedChoice(mItem.mDiscIndex, mItem.mSectionIndex, mItem.mOptionIndex)), false); - mChoiceDropdown.setOnItemClickListener(this); + mBinding.dropdownChoice.setOnItemClickListener(this); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivity.java index 45a48a1cfa..fa42a7a78c 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivity.java @@ -28,6 +28,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder; import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ActivitySettingsBinding; import org.dolphinemu.dolphinemu.ui.main.MainPresenter; import org.dolphinemu.dolphinemu.utils.FileBrowserHelper; import org.dolphinemu.dolphinemu.utils.InsetsHelper; @@ -81,7 +82,8 @@ public final class SettingsActivity extends AppCompatActivity implements Setting MainPresenter.skipRescanningLibrary(); } - setContentView(R.layout.activity_settings); + ActivitySettingsBinding binding = ActivitySettingsBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); WindowCompat.setDecorFitsSystemWindows(getWindow(), false); @@ -96,21 +98,17 @@ public final class SettingsActivity extends AppCompatActivity implements Setting mPresenter = new SettingsActivityPresenter(this, getSettings()); mPresenter.onCreate(savedInstanceState, menuTag, gameID, revision, isWii, this); - MaterialToolbar tb = findViewById(R.id.toolbar_settings); - mToolbarLayout = findViewById(R.id.toolbar_settings_layout); - setSupportActionBar(tb); + mToolbarLayout = binding.toolbarSettingsLayout; + setSupportActionBar(binding.toolbarSettings); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - AppBarLayout appBarLayout = findViewById(R.id.appbar_settings); - FrameLayout frameLayout = findViewById(R.id.frame_content_settings); - // TODO: Remove this when CollapsingToolbarLayouts are fixed by Google // https://github.com/material-components/material-components-android/issues/1310 ViewCompat.setOnApplyWindowInsetsListener(mToolbarLayout, null); - View workaroundView = findViewById(R.id.workaround_view); - InsetsHelper.setUpSettingsLayout(this, appBarLayout, frameLayout, workaroundView); - ThemeHelper.enableScrollTint(this, tb, appBarLayout); + InsetsHelper.setUpSettingsLayout(this, binding.appbarSettings, binding.frameContentSettings, + binding.workaroundView); + ThemeHelper.enableScrollTint(this, binding.toolbarSettings, binding.appbarSettings); } @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java index d8ceb5ba29..42f7d5cb04 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java @@ -8,7 +8,6 @@ import android.content.Intent; import android.os.Build; import android.provider.DocumentsContract; import android.view.LayoutInflater; -import android.view.View; import android.view.ViewGroup; import android.widget.TextView; @@ -21,6 +20,12 @@ import com.google.android.material.slider.Slider; import com.google.android.material.textfield.TextInputEditText; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.DialogInputStringBinding; +import org.dolphinemu.dolphinemu.databinding.DialogSliderBinding; +import org.dolphinemu.dolphinemu.databinding.ListItemHeaderBinding; +import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding; +import org.dolphinemu.dolphinemu.databinding.ListItemSettingCheckboxBinding; +import org.dolphinemu.dolphinemu.databinding.ListItemSubmenuBinding; import org.dolphinemu.dolphinemu.dialogs.MotionAlertDialog; import org.dolphinemu.dolphinemu.features.settings.model.Settings; import org.dolphinemu.dolphinemu.features.settings.model.view.CheckBoxSetting; @@ -79,59 +84,50 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde mClickedPosition = -1; } + @NonNull @Override - public SettingViewHolder onCreateViewHolder(ViewGroup parent, int viewType) + public SettingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view; LayoutInflater inflater = LayoutInflater.from(parent.getContext()); - switch (viewType) { case SettingsItem.TYPE_HEADER: - view = inflater.inflate(R.layout.list_item_header, parent, false); - return new HeaderViewHolder(view, this); + return new HeaderViewHolder(ListItemHeaderBinding.inflate(inflater), this); case SettingsItem.TYPE_CHECKBOX: - view = inflater.inflate(R.layout.list_item_setting_checkbox, parent, false); - return new CheckBoxSettingViewHolder(view, this); + return new CheckBoxSettingViewHolder(ListItemSettingCheckboxBinding.inflate(inflater), + this); case SettingsItem.TYPE_STRING_SINGLE_CHOICE: case SettingsItem.TYPE_SINGLE_CHOICE_DYNAMIC_DESCRIPTIONS: case SettingsItem.TYPE_SINGLE_CHOICE: - view = inflater.inflate(R.layout.list_item_setting, parent, false); - return new SingleChoiceViewHolder(view, this); + return new SingleChoiceViewHolder(ListItemSettingBinding.inflate(inflater), this); case SettingsItem.TYPE_SLIDER: - view = inflater.inflate(R.layout.list_item_setting, parent, false); - return new SliderViewHolder(view, this, mContext); + return new SliderViewHolder(ListItemSettingBinding.inflate(inflater), this, mContext); case SettingsItem.TYPE_SUBMENU: - view = inflater.inflate(R.layout.list_item_submenu, parent, false); - return new SubmenuViewHolder(view, this); + return new SubmenuViewHolder(ListItemSubmenuBinding.inflate(inflater), this); case SettingsItem.TYPE_INPUT_BINDING: - view = inflater.inflate(R.layout.list_item_setting, parent, false); - return new InputBindingSettingViewHolder(view, this, mContext); + return new InputBindingSettingViewHolder(ListItemSettingBinding.inflate(inflater), this, + mContext); case SettingsItem.TYPE_RUMBLE_BINDING: - view = inflater.inflate(R.layout.list_item_setting, parent, false); - return new RumbleBindingViewHolder(view, this, mContext); + return new RumbleBindingViewHolder(ListItemSettingBinding.inflate(inflater), this, + mContext); case SettingsItem.TYPE_FILE_PICKER: - view = inflater.inflate(R.layout.list_item_setting, parent, false); - return new FilePickerViewHolder(view, this); + return new FilePickerViewHolder(ListItemSettingBinding.inflate(inflater), this); case SettingsItem.TYPE_RUN_RUNNABLE: - view = inflater.inflate(R.layout.list_item_setting, parent, false); - return new RunRunnableViewHolder(view, this, mContext); + return new RunRunnableViewHolder(ListItemSettingBinding.inflate(inflater), this, mContext); case SettingsItem.TYPE_STRING: - view = inflater.inflate(R.layout.list_item_setting, parent, false); - return new InputStringSettingViewHolder(view, this); + return new InputStringSettingViewHolder(ListItemSettingBinding.inflate(inflater), this); case SettingsItem.TYPE_HYPERLINK_HEADER: - view = inflater.inflate(R.layout.list_item_header, parent, false); - return new HeaderHyperLinkViewHolder(view, this, mContext); + return new HeaderHyperLinkViewHolder(ListItemHeaderBinding.inflate(inflater), this); default: throw new IllegalArgumentException("Invalid view type: " + viewType); @@ -139,7 +135,7 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde } @Override - public void onBindViewHolder(SettingViewHolder holder, int position) + public void onBindViewHolder(@NonNull SettingViewHolder holder, int position) { holder.bind(getItem(position)); } @@ -206,12 +202,12 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde { LayoutInflater inflater = LayoutInflater.from(mContext); - View dialogView = inflater.inflate(R.layout.dialog_input_string, null); - TextInputEditText input = dialogView.findViewById(R.id.input); + DialogInputStringBinding binding = DialogInputStringBinding.inflate(inflater); + TextInputEditText input = binding.input; input.setText(item.getSelectedValue(getSettings())); mDialog = new MaterialAlertDialogBuilder(mView.getActivity()) - .setView(dialogView) + .setView(binding.getRoot()) .setMessage(item.getDescription()) .setPositiveButton(R.string.ok, (dialogInterface, i) -> { @@ -275,26 +271,25 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde mSeekbarProgress = item.getSelectedValue(getSettings()); LayoutInflater inflater = LayoutInflater.from(mView.getActivity()); - View view = inflater.inflate(R.layout.dialog_slider, null); - - mDialog = new MaterialAlertDialogBuilder(mView.getActivity()) - .setTitle(item.getName()) - .setView(view) - .setPositiveButton(R.string.ok, this) - .show(); + DialogSliderBinding binding = DialogSliderBinding.inflate(inflater); - mTextSliderValue = view.findViewById(R.id.text_value); + mTextSliderValue = binding.textValue; mTextSliderValue.setText(String.valueOf(mSeekbarProgress)); - TextView units = view.findViewById(R.id.text_units); - units.setText(item.getUnits()); + binding.textUnits.setText(item.getUnits()); - Slider slider = view.findViewById(R.id.slider); + Slider slider = binding.slider; slider.setValueFrom(item.getMin()); slider.setValueTo(item.getMax()); slider.setValue(mSeekbarProgress); slider.setStepSize(1); slider.addOnChangeListener(this); + + mDialog = new MaterialAlertDialogBuilder(mView.getActivity()) + .setTitle(item.getName()) + .setView(binding.getRoot()) + .setPositiveButton(R.string.ok, this) + .show(); } public void onSubmenuClick(SubmenuSetting item) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragment.java index 025c98e56c..f55037c207 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragment.java @@ -17,6 +17,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.divider.MaterialDividerItemDecoration; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.FragmentSettingsBinding; import org.dolphinemu.dolphinemu.features.settings.model.Settings; import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem; import org.dolphinemu.dolphinemu.utils.InsetsHelper; @@ -74,6 +75,8 @@ public final class SettingsFragment extends Fragment implements SettingsFragment titles.put(MenuTag.WIIMOTE_EXTENSION_4, R.string.wiimote_extension_7); } + private FragmentSettingsBinding mBinding; + public static Fragment newInstance(MenuTag menuTag, String gameId, Bundle extras) { SettingsFragment fragment = new SettingsFragment(); @@ -114,12 +117,13 @@ public final class SettingsFragment extends Fragment implements SettingsFragment mPresenter.onCreate(menuTag, gameId, args); } - @Nullable + @NonNull @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_settings, container, false); + mBinding = FragmentSettingsBinding.inflate(inflater, container, false); + return mBinding.getRoot(); } @Override @@ -135,7 +139,7 @@ public final class SettingsFragment extends Fragment implements SettingsFragment LinearLayoutManager manager = new LinearLayoutManager(getActivity()); - RecyclerView recyclerView = view.findViewById(R.id.list_settings); + RecyclerView recyclerView = mBinding.listSettings; recyclerView.setAdapter(mAdapter); recyclerView.setLayoutManager(manager); @@ -152,6 +156,13 @@ public final class SettingsFragment extends Fragment implements SettingsFragment } @Override + public void onDestroyView() + { + super.onDestroyView(); + mBinding = null; + } + + @Override public void onDetach() { super.onDetach(); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/CheckBoxSettingViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/CheckBoxSettingViewHolder.java index 11fe903421..61cb031074 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/CheckBoxSettingViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/CheckBoxSettingViewHolder.java @@ -3,12 +3,10 @@ package org.dolphinemu.dolphinemu.features.settings.ui.viewholder; import android.view.View; -import android.widget.CheckBox; -import android.widget.TextView; import androidx.annotation.Nullable; -import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemSettingCheckboxBinding; import org.dolphinemu.dolphinemu.features.settings.model.view.CheckBoxSetting; import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem; import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter; @@ -17,22 +15,12 @@ public final class CheckBoxSettingViewHolder extends SettingViewHolder { private CheckBoxSetting mItem; - private TextView mTextSettingName; - private TextView mTextSettingDescription; + private final ListItemSettingCheckboxBinding mBinding; - private CheckBox mCheckbox; - - public CheckBoxSettingViewHolder(View itemView, SettingsAdapter adapter) - { - super(itemView, adapter); - } - - @Override - protected void findViews(View root) + public CheckBoxSettingViewHolder(ListItemSettingCheckboxBinding binding, SettingsAdapter adapter) { - mTextSettingName = root.findViewById(R.id.text_setting_name); - mTextSettingDescription = root.findViewById(R.id.text_setting_description); - mCheckbox = root.findViewById(R.id.checkbox); + super(binding.getRoot(), adapter); + mBinding = binding; } @Override @@ -40,12 +28,12 @@ public final class CheckBoxSettingViewHolder extends SettingViewHolder { mItem = (CheckBoxSetting) item; - mTextSettingName.setText(item.getName()); - mTextSettingDescription.setText(item.getDescription()); + mBinding.textSettingName.setText(item.getName()); + mBinding.textSettingDescription.setText(item.getDescription()); - mCheckbox.setChecked(mItem.isChecked(getAdapter().getSettings())); + mBinding.checkbox.setChecked(mItem.isChecked(getAdapter().getSettings())); - setStyle(mTextSettingName, mItem); + setStyle(mBinding.textSettingName, mItem); } @Override @@ -57,11 +45,11 @@ public final class CheckBoxSettingViewHolder extends SettingViewHolder return; } - mCheckbox.toggle(); + mBinding.checkbox.toggle(); - getAdapter().onBooleanClick(mItem, getBindingAdapterPosition(), mCheckbox.isChecked()); + getAdapter().onBooleanClick(mItem, getBindingAdapterPosition(), mBinding.checkbox.isChecked()); - setStyle(mTextSettingName, mItem); + setStyle(mBinding.textSettingName, mItem); } @Nullable @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/FilePickerViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/FilePickerViewHolder.java index f0bad3389c..87b84bd35c 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/FilePickerViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/FilePickerViewHolder.java @@ -2,14 +2,13 @@ package org.dolphinemu.dolphinemu.features.settings.ui.viewholder; -import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.view.View; -import android.widget.TextView; import androidx.annotation.Nullable; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding; import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker; import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem; import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter; @@ -22,23 +21,12 @@ public final class FilePickerViewHolder extends SettingViewHolder private FilePicker mFilePicker; private SettingsItem mItem; - private TextView mTextSettingName; - private TextView mTextSettingDescription; + private final ListItemSettingBinding mBinding; - private Drawable mDefaultBackground; - - public FilePickerViewHolder(View itemView, SettingsAdapter adapter) - { - super(itemView, adapter); - } - - @Override - protected void findViews(View root) + public FilePickerViewHolder(ListItemSettingBinding binding, SettingsAdapter adapter) { - mTextSettingName = root.findViewById(R.id.text_setting_name); - mTextSettingDescription = root.findViewById(R.id.text_setting_description); - - mDefaultBackground = root.getBackground(); + super(binding.getRoot(), adapter); + mBinding = binding; } @Override @@ -51,18 +39,18 @@ public final class FilePickerViewHolder extends SettingViewHolder if (FileBrowserHelper.isPathEmptyOrValid(path)) { - itemView.setBackground(mDefaultBackground); + itemView.setBackground(mBinding.getRoot().getBackground()); } else { itemView.setBackgroundResource(R.drawable.invalid_setting_background); } - mTextSettingName.setText(item.getName()); + mBinding.textSettingName.setText(item.getName()); if (!TextUtils.isEmpty(item.getDescription())) { - mTextSettingDescription.setText(item.getDescription()); + mBinding.textSettingDescription.setText(item.getDescription()); } else { @@ -75,10 +63,10 @@ public final class FilePickerViewHolder extends SettingViewHolder } } - mTextSettingDescription.setText(path); + mBinding.textSettingDescription.setText(path); } - setStyle(mTextSettingName, mItem); + setStyle(mBinding.textSettingName, mItem); } @Override @@ -100,7 +88,7 @@ public final class FilePickerViewHolder extends SettingViewHolder getAdapter().onFilePickerFileClick(mItem, position); } - setStyle(mTextSettingName, mItem); + setStyle(mBinding.textSettingName, mItem); } @Nullable @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/HeaderHyperLinkViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/HeaderHyperLinkViewHolder.java index c3abf79c24..2d3e9ac5d0 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/HeaderHyperLinkViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/HeaderHyperLinkViewHolder.java @@ -2,33 +2,35 @@ package org.dolphinemu.dolphinemu.features.settings.ui.viewholder; -import android.content.Context; import android.text.method.LinkMovementMethod; -import android.view.View; + +import androidx.annotation.NonNull; import com.google.android.material.color.MaterialColors; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemHeaderBinding; import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem; import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter; public final class HeaderHyperLinkViewHolder extends HeaderViewHolder { - private Context mContext; + private final ListItemHeaderBinding mBinding; - public HeaderHyperLinkViewHolder(View itemView, SettingsAdapter adapter, Context context) + public HeaderHyperLinkViewHolder(@NonNull ListItemHeaderBinding binding, SettingsAdapter adapter) { - super(itemView, adapter); - mContext = context; + super(binding, adapter); + mBinding = binding; itemView.setOnClickListener(null); } @Override - public void bind(SettingsItem item) + public void bind(@NonNull SettingsItem item) { super.bind(item); - mHeaderName.setMovementMethod(LinkMovementMethod.getInstance()); - mHeaderName.setLinkTextColor(MaterialColors.getColor(itemView, R.attr.colorTertiary)); + mBinding.textHeaderName.setMovementMethod(LinkMovementMethod.getInstance()); + mBinding.textHeaderName.setLinkTextColor( + MaterialColors.getColor(itemView, R.attr.colorTertiary)); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/HeaderViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/HeaderViewHolder.java index 4422d9081d..889b087396 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/HeaderViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/HeaderViewHolder.java @@ -3,34 +3,29 @@ package org.dolphinemu.dolphinemu.features.settings.ui.viewholder; import android.view.View; -import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem; import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter; +import org.dolphinemu.dolphinemu.databinding.ListItemHeaderBinding; public class HeaderViewHolder extends SettingViewHolder { - protected TextView mHeaderName; + private final ListItemHeaderBinding mBinding; - public HeaderViewHolder(View itemView, SettingsAdapter adapter) + public HeaderViewHolder(@NonNull ListItemHeaderBinding binding, SettingsAdapter adapter) { - super(itemView, adapter); + super(binding.getRoot(), adapter); itemView.setOnClickListener(null); + mBinding = binding; } @Override - protected void findViews(View root) + public void bind(@NonNull SettingsItem item) { - mHeaderName = root.findViewById(R.id.text_header_name); - } - - @Override - public void bind(SettingsItem item) - { - mHeaderName.setText(item.getName()); + mBinding.textHeaderName.setText(item.getName()); } @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/InputBindingSettingViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/InputBindingSettingViewHolder.java index ba861cb814..b61fcc458b 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/InputBindingSettingViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/InputBindingSettingViewHolder.java @@ -5,12 +5,12 @@ package org.dolphinemu.dolphinemu.features.settings.ui.viewholder; import android.content.Context; import android.content.SharedPreferences; import android.view.View; -import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; -import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding; import org.dolphinemu.dolphinemu.features.settings.model.view.InputBindingSetting; import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem; import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter; @@ -19,37 +19,30 @@ public final class InputBindingSettingViewHolder extends SettingViewHolder { private InputBindingSetting mItem; - private TextView mTextSettingName; - private TextView mTextSettingDescription; + private final Context mContext; - private Context mContext; + private final ListItemSettingBinding mBinding; - public InputBindingSettingViewHolder(View itemView, SettingsAdapter adapter, Context context) + public InputBindingSettingViewHolder(@NonNull ListItemSettingBinding binding, + SettingsAdapter adapter, Context context) { - super(itemView, adapter); - + super(binding.getRoot(), adapter); + mBinding = binding; mContext = context; } @Override - protected void findViews(View root) - { - mTextSettingName = root.findViewById(R.id.text_setting_name); - mTextSettingDescription = root.findViewById(R.id.text_setting_description); - } - - @Override public void bind(SettingsItem item) { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext); mItem = (InputBindingSetting) item; - mTextSettingName.setText(mItem.getName()); - mTextSettingDescription + mBinding.textSettingName.setText(mItem.getName()); + mBinding.textSettingDescription .setText(sharedPreferences.getString(mItem.getKey() + mItem.getGameId(), "")); - setStyle(mTextSettingName, mItem); + setStyle(mBinding.textSettingName, mItem); } @Override @@ -63,7 +56,7 @@ public final class InputBindingSettingViewHolder extends SettingViewHolder getAdapter().onInputBindingClick(mItem, getBindingAdapterPosition()); - setStyle(mTextSettingName, mItem); + setStyle(mBinding.textSettingName, mItem); } @Nullable @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/InputStringSettingViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/InputStringSettingViewHolder.java index da36fb1953..070284d38a 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/InputStringSettingViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/InputStringSettingViewHolder.java @@ -4,11 +4,11 @@ package org.dolphinemu.dolphinemu.features.settings.ui.viewholder; import android.text.TextUtils; import android.view.View; -import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding; import org.dolphinemu.dolphinemu.features.settings.model.view.InputStringSetting; import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem; import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter; @@ -17,19 +17,13 @@ public final class InputStringSettingViewHolder extends SettingViewHolder { private InputStringSetting mInputString; - private TextView mTextSettingName; - private TextView mTextSettingDescription; + private final ListItemSettingBinding mBinding; - public InputStringSettingViewHolder(View itemView, SettingsAdapter adapter) + public InputStringSettingViewHolder(@NonNull ListItemSettingBinding binding, + SettingsAdapter adapter) { - super(itemView, adapter); - } - - @Override - protected void findViews(View root) - { - mTextSettingName = root.findViewById(R.id.text_setting_name); - mTextSettingDescription = root.findViewById(R.id.text_setting_description); + super(binding.getRoot(), adapter); + mBinding = binding; } @Override @@ -39,18 +33,18 @@ public final class InputStringSettingViewHolder extends SettingViewHolder String inputString = mInputString.getSelectedValue(getAdapter().getSettings()); - mTextSettingName.setText(item.getName()); + mBinding.textSettingName.setText(item.getName()); if (!TextUtils.isEmpty(inputString)) { - mTextSettingDescription.setText(inputString); + mBinding.textSettingDescription.setText(inputString); } else { - mTextSettingDescription.setText(item.getDescription()); + mBinding.textSettingDescription.setText(item.getDescription()); } - setStyle(mTextSettingName, mInputString); + setStyle(mBinding.textSettingName, mInputString); } @Override @@ -62,11 +56,11 @@ public final class InputStringSettingViewHolder extends SettingViewHolder return; } - int position = getAdapterPosition(); + int position = getBindingAdapterPosition(); getAdapter().onInputStringClick(mInputString, position); - setStyle(mTextSettingName, mInputString); + setStyle(mBinding.textSettingName, mInputString); } @Nullable @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/RumbleBindingViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/RumbleBindingViewHolder.java index 4646dfa37a..3b7a6b0f75 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/RumbleBindingViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/RumbleBindingViewHolder.java @@ -5,12 +5,12 @@ package org.dolphinemu.dolphinemu.features.settings.ui.viewholder; import android.content.Context; import android.content.SharedPreferences; import android.view.View; -import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; -import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding; import org.dolphinemu.dolphinemu.features.settings.model.view.RumbleBindingSetting; import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem; import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter; @@ -19,37 +19,30 @@ public class RumbleBindingViewHolder extends SettingViewHolder { private RumbleBindingSetting mItem; - private TextView mTextSettingName; - private TextView mTextSettingDescription; + private final Context mContext; - private Context mContext; + private final ListItemSettingBinding mBinding; - public RumbleBindingViewHolder(View itemView, SettingsAdapter adapter, Context context) + public RumbleBindingViewHolder(@NonNull ListItemSettingBinding binding, SettingsAdapter adapter, + Context context) { - super(itemView, adapter); - + super(binding.getRoot(), adapter); + mBinding = binding; mContext = context; } @Override - protected void findViews(View root) - { - mTextSettingName = root.findViewById(R.id.text_setting_name); - mTextSettingDescription = root.findViewById(R.id.text_setting_description); - } - - @Override public void bind(SettingsItem item) { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext); mItem = (RumbleBindingSetting) item; - mTextSettingName.setText(item.getName()); - mTextSettingDescription + mBinding.textSettingName.setText(item.getName()); + mBinding.textSettingDescription .setText(sharedPreferences.getString(mItem.getKey() + mItem.getGameId(), "")); - setStyle(mTextSettingName, mItem); + setStyle(mBinding.textSettingName, mItem); } @Override @@ -63,7 +56,7 @@ public class RumbleBindingViewHolder extends SettingViewHolder getAdapter().onInputBindingClick(mItem, getBindingAdapterPosition()); - setStyle(mTextSettingName, mItem); + setStyle(mBinding.textSettingName, mItem); } @Nullable @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/RunRunnableViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/RunRunnableViewHolder.java index 8d7966ab14..cc78143c8c 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/RunRunnableViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/RunRunnableViewHolder.java @@ -4,14 +4,15 @@ package org.dolphinemu.dolphinemu.features.settings.ui.viewholder; import android.content.Context; import android.view.View; -import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding; import org.dolphinemu.dolphinemu.features.settings.model.view.RunRunnable; import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem; import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter; @@ -22,30 +23,23 @@ public final class RunRunnableViewHolder extends SettingViewHolder private final Context mContext; - private TextView mTextSettingName; - private TextView mTextSettingDescription; + private final ListItemSettingBinding mBinding; - public RunRunnableViewHolder(View itemView, SettingsAdapter adapter, Context context) + public RunRunnableViewHolder(@NonNull ListItemSettingBinding binding, SettingsAdapter adapter, + Context context) { - super(itemView, adapter); - + super(binding.getRoot(), adapter); + mBinding = binding; mContext = context; } @Override - protected void findViews(View root) - { - mTextSettingName = root.findViewById(R.id.text_setting_name); - mTextSettingDescription = root.findViewById(R.id.text_setting_description); - } - - @Override public void bind(SettingsItem item) { mItem = (RunRunnable) item; - mTextSettingName.setText(item.getName()); - mTextSettingDescription.setText(item.getDescription()); + mBinding.textSettingName.setText(item.getName()); + mBinding.textSettingDescription.setText(item.getDescription()); } @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.java index 634c75c223..9f90b335cd 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.java @@ -32,8 +32,6 @@ public abstract class SettingViewHolder extends RecyclerView.ViewHolder itemView.setOnClickListener(this); itemView.setOnLongClickListener(this); - - findViews(itemView); } protected SettingsAdapter getAdapter() @@ -57,13 +55,6 @@ public abstract class SettingViewHolder extends RecyclerView.ViewHolder } /** - * Gets handles to all this ViewHolder's child views using their XML-defined identifiers. - * - * @param root The newly inflated top-level view. - */ - protected abstract void findViews(View root); - - /** * Called by the adapter to set this ViewHolder's child views to display the list item * it must now represent. * diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SingleChoiceViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SingleChoiceViewHolder.java index 57bb78d1e2..19b174e9b8 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SingleChoiceViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SingleChoiceViewHolder.java @@ -5,11 +5,11 @@ package org.dolphinemu.dolphinemu.features.settings.ui.viewholder; import android.content.res.Resources; import android.text.TextUtils; import android.view.View; -import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding; import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem; import org.dolphinemu.dolphinemu.features.settings.model.view.SingleChoiceSetting; import org.dolphinemu.dolphinemu.features.settings.model.view.SingleChoiceSettingDynamicDescriptions; @@ -20,19 +20,12 @@ public final class SingleChoiceViewHolder extends SettingViewHolder { private SettingsItem mItem; - private TextView mTextSettingName; - private TextView mTextSettingDescription; + private final ListItemSettingBinding mBinding; - public SingleChoiceViewHolder(View itemView, SettingsAdapter adapter) + public SingleChoiceViewHolder(@NonNull ListItemSettingBinding binding, SettingsAdapter adapter) { - super(itemView, adapter); - } - - @Override - protected void findViews(View root) - { - mTextSettingName = root.findViewById(R.id.text_setting_name); - mTextSettingDescription = root.findViewById(R.id.text_setting_description); + super(binding.getRoot(), adapter); + mBinding = binding; } @Override @@ -40,24 +33,24 @@ public final class SingleChoiceViewHolder extends SettingViewHolder { mItem = item; - mTextSettingName.setText(item.getName()); + mBinding.textSettingName.setText(item.getName()); if (!TextUtils.isEmpty(item.getDescription())) { - mTextSettingDescription.setText(item.getDescription()); + mBinding.textSettingDescription.setText(item.getDescription()); } else if (item instanceof SingleChoiceSetting) { SingleChoiceSetting setting = (SingleChoiceSetting) item; int selected = setting.getSelectedValue(getAdapter().getSettings()); - Resources resMgr = mTextSettingDescription.getContext().getResources(); + Resources resMgr = mBinding.textSettingDescription.getContext().getResources(); String[] choices = resMgr.getStringArray(setting.getChoicesId()); int[] values = resMgr.getIntArray(setting.getValuesId()); for (int i = 0; i < values.length; ++i) { if (values[i] == selected) { - mTextSettingDescription.setText(choices[i]); + mBinding.textSettingDescription.setText(choices[i]); } } } @@ -67,26 +60,26 @@ public final class SingleChoiceViewHolder extends SettingViewHolder String[] choices = setting.getChoices(); int valueIndex = setting.getSelectedValueIndex(getAdapter().getSettings()); if (valueIndex != -1) - mTextSettingDescription.setText(choices[valueIndex]); + mBinding.textSettingDescription.setText(choices[valueIndex]); } else if (item instanceof SingleChoiceSettingDynamicDescriptions) { SingleChoiceSettingDynamicDescriptions setting = (SingleChoiceSettingDynamicDescriptions) item; int selected = setting.getSelectedValue(getAdapter().getSettings()); - Resources resMgr = mTextSettingDescription.getContext().getResources(); + Resources resMgr = mBinding.textSettingDescription.getContext().getResources(); String[] choices = resMgr.getStringArray(setting.getDescriptionChoicesId()); int[] values = resMgr.getIntArray(setting.getDescriptionValuesId()); for (int i = 0; i < values.length; ++i) { if (values[i] == selected) { - mTextSettingDescription.setText(choices[i]); + mBinding.textSettingDescription.setText(choices[i]); } } } - setStyle(mTextSettingName, mItem); + setStyle(mBinding.textSettingName, mItem); } @Override @@ -113,7 +106,7 @@ public final class SingleChoiceViewHolder extends SettingViewHolder (SingleChoiceSettingDynamicDescriptions) mItem, position); } - setStyle(mTextSettingName, mItem); + setStyle(mBinding.textSettingName, mItem); } @Nullable @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SliderViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SliderViewHolder.java index a5f7778f2a..1f60a9825a 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SliderViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SliderViewHolder.java @@ -5,57 +5,51 @@ package org.dolphinemu.dolphinemu.features.settings.ui.viewholder; import android.content.Context; import android.text.TextUtils; import android.view.View; -import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding; import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem; import org.dolphinemu.dolphinemu.features.settings.model.view.SliderSetting; import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter; public final class SliderViewHolder extends SettingViewHolder { - private Context mContext; + private final Context mContext; private SliderSetting mItem; - private TextView mTextSettingName; - private TextView mTextSettingDescription; + private final ListItemSettingBinding mBinding; - public SliderViewHolder(View itemView, SettingsAdapter adapter, Context context) + public SliderViewHolder(@NonNull ListItemSettingBinding binding, SettingsAdapter adapter, + Context context) { - super(itemView, adapter); - + super(binding.getRoot(), adapter); + mBinding = binding; mContext = context; } @Override - protected void findViews(View root) - { - mTextSettingName = root.findViewById(R.id.text_setting_name); - mTextSettingDescription = root.findViewById(R.id.text_setting_description); - } - - @Override public void bind(SettingsItem item) { mItem = (SliderSetting) item; - mTextSettingName.setText(item.getName()); + mBinding.textSettingName.setText(item.getName()); if (!TextUtils.isEmpty(item.getDescription())) { - mTextSettingDescription.setText(item.getDescription()); + mBinding.textSettingDescription.setText(item.getDescription()); } else { - mTextSettingDescription.setText(mContext + mBinding.textSettingDescription.setText(mContext .getString(R.string.slider_setting_value, mItem.getSelectedValue(getAdapter().getSettings()), mItem.getUnits())); } - setStyle(mTextSettingName, mItem); + setStyle(mBinding.textSettingName, mItem); } @Override @@ -69,7 +63,7 @@ public final class SliderViewHolder extends SettingViewHolder getAdapter().onSliderClick(mItem, getBindingAdapterPosition()); - setStyle(mTextSettingName, mItem); + setStyle(mBinding.textSettingName, mItem); } @Nullable @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SubmenuViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SubmenuViewHolder.java index d5af3cc162..828e538874 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SubmenuViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SubmenuViewHolder.java @@ -3,11 +3,11 @@ package org.dolphinemu.dolphinemu.features.settings.ui.viewholder; import android.view.View; -import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.ListItemSubmenuBinding; import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem; import org.dolphinemu.dolphinemu.features.settings.model.view.SubmenuSetting; import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter; @@ -16,17 +16,12 @@ public final class SubmenuViewHolder extends SettingViewHolder { private SubmenuSetting mItem; - private TextView mTextSettingName; + private final ListItemSubmenuBinding mBinding; - public SubmenuViewHolder(View itemView, SettingsAdapter adapter) + public SubmenuViewHolder(@NonNull ListItemSubmenuBinding binding, SettingsAdapter adapter) { - super(itemView, adapter); - } - - @Override - protected void findViews(View root) - { - mTextSettingName = root.findViewById(R.id.text_setting_name); + super(binding.getRoot(), adapter); + mBinding = binding; } @Override @@ -34,7 +29,7 @@ public final class SubmenuViewHolder extends SettingViewHolder { mItem = (SubmenuSetting) item; - mTextSettingName.setText(item.getName()); + mBinding.textSettingName.setText(item.getName()); } @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.java index 152e1aca64..b2c392635e 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.java @@ -5,7 +5,6 @@ package org.dolphinemu.dolphinemu.features.sysupdate.ui; import android.app.Dialog; import android.content.pm.ActivityInfo; import android.os.Bundle; -import android.view.View; import android.widget.Button; import androidx.annotation.NonNull; @@ -15,9 +14,9 @@ import androidx.fragment.app.DialogFragment; import androidx.lifecycle.ViewModelProvider; import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.progressindicator.LinearProgressIndicator; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.DialogProgressBinding; public class SystemUpdateProgressBarDialogFragment extends DialogFragment { @@ -33,20 +32,22 @@ public class SystemUpdateProgressBarDialogFragment extends DialogFragment SystemUpdateViewModel viewModel = new ViewModelProvider(requireActivity()).get(SystemUpdateViewModel.class); - View dialogView = getLayoutInflater().inflate(R.layout.dialog_progress, null, false); - LinearProgressIndicator progressBar = dialogView.findViewById(R.id.update_progress); + DialogProgressBinding dialogProgressBinding = + DialogProgressBinding.inflate(getLayoutInflater()); // We need to set the message to something here, otherwise the text will not appear when we set it later. AlertDialog progressDialog = new MaterialAlertDialogBuilder(requireContext()) .setTitle(getString(R.string.updating)) .setMessage("") .setNegativeButton(getString(R.string.cancel), null) - .setView(dialogView) + .setView(dialogProgressBinding.getRoot()) .setCancelable(false) .create(); viewModel.getProgressData() - .observe(this, (@Nullable Integer progress) -> progressBar.setProgress(progress)); + .observe(this, (@Nullable + Integer progress) -> dialogProgressBinding.updateProgress.setProgress( + progress)); viewModel.getTotalData().observe(this, (@Nullable Integer total) -> { @@ -55,7 +56,7 @@ public class SystemUpdateProgressBarDialogFragment extends DialogFragment return; } - progressBar.setMax(total); + dialogProgressBinding.updateProgress.setMax(total); }); viewModel.getTitleIdData().observe(this, (@Nullable Long titleId) -> progressDialog.setMessage( diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/ConvertFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/ConvertFragment.java index 555401bfa3..ec67b32061 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/ConvertFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/ConvertFragment.java @@ -13,7 +13,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; -import android.widget.CheckBox; import androidx.annotation.NonNull; import androidx.annotation.StringRes; @@ -27,6 +26,8 @@ import com.google.android.material.textfield.TextInputLayout; import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.databinding.DialogProgressBinding; +import org.dolphinemu.dolphinemu.databinding.FragmentConvertBinding; import org.dolphinemu.dolphinemu.model.GameFile; import org.dolphinemu.dolphinemu.services.GameFileCacheManager; import org.dolphinemu.dolphinemu.ui.platform.Platform; @@ -114,21 +115,13 @@ public class ConvertFragment extends Fragment implements View.OnClickListener 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; private volatile boolean mCanceled; private volatile Thread mThread = null; + private FragmentConvertBinding mBinding; + public static ConvertFragment newInstance(String gamePath) { Bundle args = new Bundle(); @@ -150,20 +143,19 @@ public class ConvertFragment extends Fragment implements View.OnClickListener public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_convert, container, false); + mBinding = FragmentConvertBinding.inflate(inflater, container, false); + return mBinding.getRoot(); } @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); + mBinding.dropdownFormat.setSaveEnabled(false); + mBinding.dropdownBlockSize.setSaveEnabled(false); + mBinding.dropdownCompression.setSaveEnabled(false); + mBinding.dropdownCompressionLevel.setSaveEnabled(false); populateFormats(); populateBlockSize(); @@ -177,35 +169,23 @@ public class ConvertFragment extends Fragment implements View.OnClickListener mCompression.addCallback(this::populateCompressionLevel); mFormat.addCallback(this::populateRemoveJunkData); - view.findViewById(R.id.button_convert).setOnClickListener(this); + mBinding.buttonConvert.setOnClickListener(this); if (savedInstanceState != null) { - setDropdownSelection(mFormatDropdown, mFormat, savedInstanceState.getInt(KEY_FORMAT)); - setDropdownSelection(mBlockSizeDropdown, mBlockSize, + setDropdownSelection(mBinding.dropdownFormat, mFormat, savedInstanceState.getInt(KEY_FORMAT)); + setDropdownSelection(mBinding.dropdownBlockSize, mBlockSize, savedInstanceState.getInt(KEY_BLOCK_SIZE)); - setDropdownSelection(mCompressionDropdown, mCompression, + setDropdownSelection(mBinding.dropdownCompression, mCompression, savedInstanceState.getInt(KEY_COMPRESSION)); - setDropdownSelection(mCompressionLevelDropdown, mCompressionLevel, + setDropdownSelection(mBinding.dropdownCompressionLevel, mCompressionLevel, savedInstanceState.getInt(KEY_COMPRESSION_LEVEL)); - mRemoveJunkDataCheckbox.setChecked(savedInstanceState.getBoolean(KEY_REMOVE_JUNK_DATA)); + mBinding.checkboxRemoveJunkData.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) { @@ -214,7 +194,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener outState.putInt(KEY_COMPRESSION, mCompression.getPosition()); outState.putInt(KEY_COMPRESSION_LEVEL, mCompressionLevel.getPosition()); - outState.putBoolean(KEY_REMOVE_JUNK_DATA, mRemoveJunkDataCheckbox.isChecked()); + outState.putBoolean(KEY_REMOVE_JUNK_DATA, mBinding.checkboxRemoveJunkData.isChecked()); } private void setDropdownSelection(MaterialAutoCompleteTextView dropdown, @@ -236,6 +216,13 @@ public class ConvertFragment extends Fragment implements View.OnClickListener joinThread(); } + @Override + public void onDestroyView() + { + super.onDestroyView(); + mBinding = null; + } + private void populateDropdown(TextInputLayout layout, MaterialAutoCompleteTextView dropdown, int entriesId, int valuesId, DropdownValue valueWrapper) { @@ -263,13 +250,15 @@ public class ConvertFragment extends Fragment implements View.OnClickListener private void populateFormats() { - populateDropdown(mFormatLayout, mFormatDropdown, R.array.convertFormatEntries, + populateDropdown(mBinding.format, mBinding.dropdownFormat, R.array.convertFormatEntries, R.array.convertFormatValues, mFormat); if (gameFile.getBlobType() == BLOB_TYPE_ISO) { - setDropdownSelection(mFormatDropdown, mFormat, mFormatDropdown.getAdapter().getCount() - 1); + setDropdownSelection(mBinding.dropdownFormat, mFormat, + mBinding.dropdownFormat.getAdapter().getCount() - 1); } - mFormatDropdown.setText(mFormatDropdown.getAdapter().getItem(mFormat.getPosition()).toString(), + mBinding.dropdownFormat.setText( + mBinding.dropdownFormat.getAdapter().getItem(mFormat.getPosition()).toString(), false); } @@ -281,25 +270,31 @@ 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? - populateDropdown(mBlockSizeLayout, mBlockSizeDropdown, R.array.convertBlockSizeGczEntries, + populateDropdown(mBinding.blockSize, mBinding.dropdownBlockSize, + R.array.convertBlockSizeGczEntries, R.array.convertBlockSizeGczValues, mBlockSize); mBlockSize.setPosition(0); - mBlockSizeDropdown.setText(mBlockSizeDropdown.getAdapter().getItem(0).toString(), false); + mBinding.dropdownBlockSize.setText( + mBinding.dropdownBlockSize.getAdapter().getItem(0).toString(), false); break; case BLOB_TYPE_WIA: - populateDropdown(mBlockSizeLayout, mBlockSizeDropdown, R.array.convertBlockSizeWiaEntries, + populateDropdown(mBinding.blockSize, mBinding.dropdownBlockSize, + R.array.convertBlockSizeWiaEntries, R.array.convertBlockSizeWiaValues, mBlockSize); mBlockSize.setPosition(0); - mBlockSizeDropdown.setText(mBlockSizeDropdown.getAdapter().getItem(0).toString(), false); + mBinding.dropdownBlockSize.setText( + mBinding.dropdownBlockSize.getAdapter().getItem(0).toString(), false); break; case BLOB_TYPE_RVZ: - populateDropdown(mBlockSizeLayout, mBlockSizeDropdown, R.array.convertBlockSizeRvzEntries, + populateDropdown(mBinding.blockSize, mBinding.dropdownBlockSize, + R.array.convertBlockSizeRvzEntries, R.array.convertBlockSizeRvzValues, mBlockSize); mBlockSize.setPosition(2); - mBlockSizeDropdown.setText(mBlockSizeDropdown.getAdapter().getItem(2).toString(), false); + mBinding.dropdownBlockSize.setText( + mBinding.dropdownBlockSize.getAdapter().getItem(2).toString(), false); break; default: - clearDropdown(mBlockSizeLayout, mBlockSizeDropdown, mBlockSize); + clearDropdown(mBinding.blockSize, mBinding.dropdownBlockSize, mBlockSize); } } @@ -308,31 +303,31 @@ public class ConvertFragment extends Fragment implements View.OnClickListener switch (mFormat.getValue(requireContext())) { case BLOB_TYPE_GCZ: - populateDropdown(mCompressionLayout, mCompressionDropdown, + populateDropdown(mBinding.compression, mBinding.dropdownCompression, R.array.convertCompressionGczEntries, R.array.convertCompressionGczValues, mCompression); mCompression.setPosition(0); - mCompressionDropdown.setText(mCompressionDropdown.getAdapter().getItem(0).toString(), - false); + mBinding.dropdownCompression.setText( + mBinding.dropdownCompression.getAdapter().getItem(0).toString(), false); break; case BLOB_TYPE_WIA: - populateDropdown(mCompressionLayout, mCompressionDropdown, + populateDropdown(mBinding.compression, mBinding.dropdownCompression, R.array.convertCompressionWiaEntries, R.array.convertCompressionWiaValues, mCompression); mCompression.setPosition(0); - mCompressionDropdown.setText(mCompressionDropdown.getAdapter().getItem(0).toString(), - false); + mBinding.dropdownCompression.setText( + mBinding.dropdownCompression.getAdapter().getItem(0).toString(), false); break; case BLOB_TYPE_RVZ: - populateDropdown(mCompressionLayout, mCompressionDropdown, + populateDropdown(mBinding.compression, mBinding.dropdownCompression, R.array.convertCompressionRvzEntries, R.array.convertCompressionRvzValues, mCompression); mCompression.setPosition(4); - mCompressionDropdown.setText(mCompressionDropdown.getAdapter().getItem(4).toString(), - false); + mBinding.dropdownCompression.setText( + mBinding.dropdownCompression.getAdapter().getItem(4).toString(), false); break; default: - clearDropdown(mCompressionLayout, mCompressionDropdown, mCompression); + clearDropdown(mBinding.compression, mBinding.dropdownCompression, mCompression); } } @@ -343,24 +338,25 @@ public class ConvertFragment extends Fragment implements View.OnClickListener case COMPRESSION_BZIP2: case COMPRESSION_LZMA: case COMPRESSION_LZMA2: - populateDropdown(mCompressionLevelLayout, mCompressionLevelDropdown, + populateDropdown(mBinding.compressionLevel, mBinding.dropdownCompressionLevel, R.array.convertCompressionLevelEntries, R.array.convertCompressionLevelValues, mCompressionLevel); mCompressionLevel.setPosition(4); - mCompressionLevelDropdown.setText( - mCompressionLevelDropdown.getAdapter().getItem(4).toString(), false); + mBinding.dropdownCompressionLevel.setText( + mBinding.dropdownCompressionLevel.getAdapter().getItem(4).toString(), false); break; case COMPRESSION_ZSTD: // TODO: Query DiscIO for the supported compression levels, like we do in DolphinQt? - populateDropdown(mCompressionLevelLayout, mCompressionLevelDropdown, + populateDropdown(mBinding.compressionLevel, mBinding.dropdownCompressionLevel, R.array.convertCompressionLevelZstdEntries, R.array.convertCompressionLevelZstdValues, mCompressionLevel); mCompressionLevel.setPosition(4); - mCompressionLevelDropdown.setText( - mCompressionLevelDropdown.getAdapter().getItem(4).toString(), false); + mBinding.dropdownCompressionLevel.setText( + mBinding.dropdownCompressionLevel.getAdapter().getItem(4).toString(), false); break; default: - clearDropdown(mCompressionLevelLayout, mCompressionLevelDropdown, mCompressionLevel); + clearDropdown(mBinding.compressionLevel, mBinding.dropdownCompressionLevel, + mCompressionLevel); } } @@ -369,15 +365,15 @@ public class ConvertFragment extends Fragment implements View.OnClickListener boolean scrubbingAllowed = mFormat.getValue(requireContext()) != BLOB_TYPE_RVZ && !gameFile.isDatelDisc(); - mRemoveJunkDataCheckbox.setEnabled(scrubbingAllowed); + mBinding.checkboxRemoveJunkData.setEnabled(scrubbingAllowed); if (!scrubbingAllowed) - mRemoveJunkDataCheckbox.setChecked(false); + mBinding.checkboxRemoveJunkData.setChecked(false); } @Override public void onClick(View view) { - boolean scrub = mRemoveJunkDataCheckbox.isChecked(); + boolean scrub = mBinding.checkboxRemoveJunkData.isChecked(); int format = mFormat.getValue(requireContext()); Runnable action = this::showSavePrompt; @@ -466,15 +462,15 @@ public class ConvertFragment extends Fragment implements View.OnClickListener mCanceled = false; - View dialogView = getLayoutInflater().inflate(R.layout.dialog_progress, null, false); - LinearProgressIndicator progressBar = dialogView.findViewById(R.id.update_progress); - progressBar.setMax(PROGRESS_RESOLUTION); + DialogProgressBinding dialogProgressBinding = + DialogProgressBinding.inflate(getLayoutInflater(), null, false); + dialogProgressBinding.updateProgress.setMax(PROGRESS_RESOLUTION); AlertDialog progressDialog = new MaterialAlertDialogBuilder(context) .setTitle(R.string.convert_converting) .setOnCancelListener((dialog) -> mCanceled = true) .setNegativeButton(getString(R.string.cancel), (dialog, i) -> dialog.dismiss()) - .setView(dialogView) + .setView(dialogProgressBinding.getRoot()) .show(); mThread = new Thread(() -> @@ -482,12 +478,13 @@ 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), - mRemoveJunkDataCheckbox.isChecked(), (text, completion) -> + mBinding.checkboxRemoveJunkData.isChecked(), (text, completion) -> { requireActivity().runOnUiThread(() -> { progressDialog.setMessage(text); - progressBar.setProgress((int) (completion * PROGRESS_RESOLUTION)); + dialogProgressBinding.updateProgress.setProgress( + (int) (completion * PROGRESS_RESOLUTION)); }); return !mCanceled; }); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java index 7af1c09dfa..142aca0641 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java @@ -13,11 +13,12 @@ import android.view.ViewGroup; import android.widget.Button; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import org.dolphinemu.dolphinemu.NativeLibrary; -import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.activities.EmulationActivity; +import org.dolphinemu.dolphinemu.databinding.FragmentEmulationBinding; import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting; import org.dolphinemu.dolphinemu.features.settings.model.Settings; import org.dolphinemu.dolphinemu.overlay.InputOverlay; @@ -41,6 +42,8 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C private EmulationActivity activity; + private FragmentEmulationBinding mBinding; + public static EmulationFragment newInstance(String[] gamePaths, boolean riivolution, boolean systemMenu) { @@ -83,20 +86,24 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C mLaunchSystemMenu = getArguments().getBoolean(KEY_SYSTEM_MENU); } - /** - * Initialize the UI and start emulation in here. - */ @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { - View contents = inflater.inflate(R.layout.fragment_emulation, container, false); + mBinding = FragmentEmulationBinding.inflate(inflater, container, false); + return mBinding.getRoot(); + } - SurfaceView surfaceView = contents.findViewById(R.id.surface_emulation); + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) + { + // The new Surface created here will get passed to the native code via onSurfaceChanged. + SurfaceView surfaceView = mBinding.surfaceEmulation; surfaceView.getHolder().addCallback(this); - mInputOverlay = contents.findViewById(R.id.surface_input_overlay); + mInputOverlay = mBinding.surfaceInputOverlay; - Button doneButton = contents.findViewById(R.id.done_control_config); + Button doneButton = mBinding.doneControlConfig; if (doneButton != null) { doneButton.setOnClickListener(v -> stopConfiguringControls()); @@ -104,7 +111,7 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C if (mInputOverlay != null) { - contents.post(() -> + view.post(() -> { int overlayX = mInputOverlay.getLeft(); int overlayY = mInputOverlay.getTop(); @@ -113,10 +120,13 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C surfaceView.getRight() - overlayX, surfaceView.getBottom() - overlayY)); }); } + } - // The new Surface created here will get passed to the native code via onSurfaceChanged. - - return contents; + @Override + public void onDestroyView() + { + super.onDestroyView(); + mBinding = null; } @Override @@ -223,7 +233,7 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C { if (mInputOverlay != null) { - requireView().findViewById(R.id.done_control_config).setVisibility(View.VISIBLE); + mBinding.doneControlConfig.setVisibility(View.VISIBLE); mInputOverlay.setIsInEditMode(true); } } @@ -232,7 +242,7 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C { if (mInputOverlay != null) { - requireView().findViewById(R.id.done_control_config).setVisibility(View.GONE); + mBinding.doneControlConfig.setVisibility(View.GONE); mInputOverlay.setIsInEditMode(false); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java index 253892aafe..dfed5871c0 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java @@ -11,21 +11,19 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.LinearLayout; -import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.activities.EmulationActivity; +import org.dolphinemu.dolphinemu.databinding.FragmentIngameMenuBinding; import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting; public final class MenuFragment extends Fragment implements View.OnClickListener { - private TextView mTitleText; - private View mPauseEmulation; - private View mUnpauseEmulation; - private static final String KEY_TITLE = "title"; private static final String KEY_WII = "wii"; private static SparseIntArray buttonsActionsMap = new SparseIntArray(); @@ -53,6 +51,8 @@ public final class MenuFragment extends Fragment implements View.OnClickListener buttonsActionsMap.append(R.id.menu_settings, EmulationActivity.MENU_ACTION_SETTINGS); } + private FragmentIngameMenuBinding mBinding; + public static MenuFragment newInstance() { MenuFragment fragment = new MenuFragment(); @@ -76,26 +76,28 @@ public final class MenuFragment extends Fragment implements View.OnClickListener return visibleFrame.bottom - visibleFrame.top - getResources().getDisplayMetrics().heightPixels; } + @NonNull @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_ingame_menu, container, false); - - LinearLayout options = rootView.findViewById(R.id.layout_options); - - mPauseEmulation = options.findViewById(R.id.menu_pause_emulation); - mUnpauseEmulation = options.findViewById(R.id.menu_unpause_emulation); + mBinding = FragmentIngameMenuBinding.inflate(inflater, container, false); + return mBinding.getRoot(); + } + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) + { updatePauseUnpauseVisibility(); if (!requireActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) { - options.findViewById(R.id.menu_overlay_controls).setVisibility(View.GONE); + mBinding.menuOverlayControls.setVisibility(View.GONE); } if (!getArguments().getBoolean(KEY_WII, true)) { - options.findViewById(R.id.menu_refresh_wiimotes).setVisibility(View.GONE); + mBinding.menuRefreshWiimotes.setVisibility(View.GONE); } int bottomPaddingRequired = getBottomPaddingRequired(); @@ -107,12 +109,13 @@ public final class MenuFragment extends Fragment implements View.OnClickListener bottomPaddingRequired += 32 * density; } - if (bottomPaddingRequired > rootView.getPaddingBottom()) + if (bottomPaddingRequired > view.getPaddingBottom()) { - rootView.setPadding(rootView.getPaddingLeft(), rootView.getPaddingTop(), - rootView.getPaddingRight(), bottomPaddingRequired); + view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), + view.getPaddingRight(), bottomPaddingRequired); } + LinearLayout options = mBinding.layoutOptions; for (int childIndex = 0; childIndex < options.getChildCount(); childIndex++) { Button button = (Button) options.getChildAt(childIndex); @@ -120,21 +123,18 @@ public final class MenuFragment extends Fragment implements View.OnClickListener button.setOnClickListener(this); } - rootView.findViewById(R.id.menu_exit).setOnClickListener(this); + mBinding.menuExit.setOnClickListener(this); - mTitleText = rootView.findViewById(R.id.text_game_title); String title = getArguments().getString(KEY_TITLE, null); if (title != null) { - mTitleText.setText(title); + mBinding.textGameTitle.setText(title); } if (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_LTR) { - rootView.post(() -> NativeLibrary.SetObscuredPixelsLeft(rootView.getWidth())); + view.post(() -> NativeLibrary.SetObscuredPixelsLeft(view.getWidth())); } - - return rootView; } @Override @@ -142,14 +142,12 @@ public final class MenuFragment extends Fragment implements View.OnClickListener { super.onResume(); - LinearLayout options = requireView().findViewById(R.id.layout_options); - boolean savestatesEnabled = BooleanSetting.MAIN_ENABLE_SAVESTATES.getBooleanGlobal(); int savestateVisibility = savestatesEnabled ? View.VISIBLE : View.GONE; - options.findViewById(R.id.menu_quicksave).setVisibility(savestateVisibility); - options.findViewById(R.id.menu_quickload).setVisibility(savestateVisibility); - options.findViewById(R.id.menu_emulation_save_root).setVisibility(savestateVisibility); - options.findViewById(R.id.menu_emulation_load_root).setVisibility(savestateVisibility); + mBinding.menuQuicksave.setVisibility(savestateVisibility); + mBinding.menuQuickload.setVisibility(savestateVisibility); + mBinding.menuEmulationSaveRoot.setVisibility(savestateVisibility); + mBinding.menuEmulationLoadRoot.setVisibility(savestateVisibility); } @Override @@ -158,14 +156,15 @@ public final class MenuFragment extends Fragment implements View.OnClickListener super.onDestroyView(); NativeLibrary.SetObscuredPixelsLeft(0); + mBinding = null; } private void updatePauseUnpauseVisibility() { boolean paused = EmulationActivity.getHasUserPausedEmulation(); - mUnpauseEmulation.setVisibility(paused ? View.VISIBLE : View.GONE); - mPauseEmulation.setVisibility(paused ? View.GONE : View.VISIBLE); + mBinding.menuUnpauseEmulation.setVisibility(paused ? View.VISIBLE : View.GONE); + mBinding.menuPauseEmulation.setVisibility(paused ? View.GONE : View.VISIBLE); } @Override @@ -178,7 +177,7 @@ public final class MenuFragment extends Fragment implements View.OnClickListener { // We could use the button parameter as the anchor here, but this often results in a tiny menu // (because the button often is in the middle of the screen), so let's use mTitleText instead - activity.showOverlayControlsMenu(mTitleText); + activity.showOverlayControlsMenu(mBinding.textGameTitle); } else if (action >= 0) { diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveLoadStateFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveLoadStateFragment.java index d07d2d4c7b..2afce4d1cf 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveLoadStateFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveLoadStateFragment.java @@ -11,12 +11,14 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.GridLayout; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.activities.EmulationActivity; +import org.dolphinemu.dolphinemu.databinding.FragmentSaveloadStateBinding; public final class SaveLoadStateFragment extends Fragment implements View.OnClickListener { @@ -59,6 +61,8 @@ public final class SaveLoadStateFragment extends Fragment implements View.OnClic private SaveOrLoad mSaveOrLoad; + private FragmentSaveloadStateBinding mBinding; + public static SaveLoadStateFragment newInstance(SaveOrLoad saveOrLoad) { SaveLoadStateFragment fragment = new SaveLoadStateFragment(); @@ -78,12 +82,19 @@ public final class SaveLoadStateFragment extends Fragment implements View.OnClic mSaveOrLoad = (SaveOrLoad) getArguments().getSerializable(KEY_SAVEORLOAD); } + @NonNull @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_saveload_state, container, false); + mBinding = FragmentSaveloadStateBinding.inflate(inflater, container, false); + return mBinding.getRoot(); + } - GridLayout grid = rootView.findViewById(R.id.grid_state_slots); + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) + { + GridLayout grid = mBinding.gridStateSlots; for (int childIndex = 0; childIndex < grid.getChildCount(); childIndex++) { Button button = (Button) grid.getChildAt(childIndex); @@ -93,8 +104,13 @@ public final class SaveLoadStateFragment extends Fragment implements View.OnClic // So that item clicked to start this Fragment is no longer the focused item. grid.requestFocus(); + } - return rootView; + @Override + public void onDestroyView() + { + super.onDestroyView(); + mBinding = null; } @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java index 96dc44d83b..2a0512e3ac 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java @@ -9,24 +9,20 @@ import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; -import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.Toolbar; import androidx.core.splashscreen.SplashScreen; import androidx.core.view.WindowCompat; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import androidx.viewpager.widget.ViewPager; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.tabs.TabLayout; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.activities.EmulationActivity; import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter; +import org.dolphinemu.dolphinemu.databinding.ActivityMainBinding; import org.dolphinemu.dolphinemu.features.settings.model.IntSetting; import org.dolphinemu.dolphinemu.features.settings.model.NativeConfig; import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag; @@ -51,16 +47,12 @@ import org.dolphinemu.dolphinemu.utils.WiiUtils; public final class MainActivity extends AppCompatActivity implements MainView, SwipeRefreshLayout.OnRefreshListener, ThemeProvider { - private ViewPager mViewPager; - private Toolbar mToolbar; - private TabLayout mTabLayout; - private AppBarLayout mAppBarLayout; - private FloatingActionButton mFab; - private int mThemeId; private final MainPresenter mPresenter = new MainPresenter(this, this); + private ActivityMainBinding mBinding; + @Override protected void onCreate(Bundle savedInstanceState) { @@ -71,19 +63,19 @@ public final class MainActivity extends AppCompatActivity ThemeHelper.setTheme(this); super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - findViews(); + mBinding = ActivityMainBinding.inflate(getLayoutInflater()); + setContentView(mBinding.getRoot()); - View workaroundView = findViewById(R.id.workaround_view); WindowCompat.setDecorFitsSystemWindows(getWindow(), false); - InsetsHelper.setUpMainLayout(this, mAppBarLayout, mFab, mViewPager, workaroundView); - ThemeHelper.enableStatusBarScrollTint(this, mAppBarLayout); + InsetsHelper.setUpMainLayout(this, mBinding.appbarMain, mBinding.buttonAddDirectory, + mBinding.pagerPlatforms, mBinding.workaroundView); + ThemeHelper.enableStatusBarScrollTint(this, mBinding.appbarMain); - setSupportActionBar(mToolbar); + setSupportActionBar(mBinding.toolbarMain); // Set up the FAB. - mFab.setOnClickListener(view -> mPresenter.onFabClick()); + mBinding.buttonAddDirectory.setOnClickListener(view -> mPresenter.onFabClick()); mPresenter.onCreate(); @@ -154,16 +146,6 @@ public final class MainActivity extends AppCompatActivity StartupHandler.setSessionTime(this); } - // TODO: Replace with a ButterKnife injection. - private void findViews() - { - mAppBarLayout = findViewById(R.id.appbar_main); - mToolbar = findViewById(R.id.toolbar_main); - mViewPager = findViewById(R.id.pager_platforms); - mTabLayout = findViewById(R.id.tabs_platforms); - mFab = findViewById(R.id.button_add_directory); - } - @Override public boolean onCreateOptionsMenu(Menu menu) { @@ -190,7 +172,7 @@ public final class MainActivity extends AppCompatActivity @Override public void setVersionString(String version) { - mToolbar.setSubtitle(version); + mBinding.toolbarMain.setSubtitle(version); } @Override @@ -351,7 +333,8 @@ public final class MainActivity extends AppCompatActivity @Nullable private PlatformGamesView getPlatformGamesView(Platform platform) { - String fragmentTag = "android:switcher:" + mViewPager.getId() + ":" + platform.toInt(); + String fragmentTag = + "android:switcher:" + mBinding.pagerPlatforms.getId() + ":" + platform.toInt(); return (PlatformGamesView) getSupportFragmentManager().findFragmentByTag(fragmentTag); } @@ -361,25 +344,27 @@ public final class MainActivity extends AppCompatActivity { PlatformPagerAdapter platformPagerAdapter = new PlatformPagerAdapter( getSupportFragmentManager(), this); - mViewPager.setAdapter(platformPagerAdapter); - mViewPager.setOffscreenPageLimit(platformPagerAdapter.getCount()); - mTabLayout.setupWithViewPager(mViewPager); - mTabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager) - { - @Override - public void onTabSelected(@NonNull TabLayout.Tab tab) - { - super.onTabSelected(tab); - IntSetting.MAIN_LAST_PLATFORM_TAB.setIntGlobal(NativeConfig.LAYER_BASE, tab.getPosition()); - } - }); + mBinding.pagerPlatforms.setAdapter(platformPagerAdapter); + mBinding.pagerPlatforms.setOffscreenPageLimit(platformPagerAdapter.getCount()); + mBinding.tabsPlatforms.setupWithViewPager(mBinding.pagerPlatforms); + mBinding.tabsPlatforms.addOnTabSelectedListener( + new TabLayout.ViewPagerOnTabSelectedListener(mBinding.pagerPlatforms) + { + @Override + public void onTabSelected(@NonNull TabLayout.Tab tab) + { + super.onTabSelected(tab); + IntSetting.MAIN_LAST_PLATFORM_TAB.setIntGlobal(NativeConfig.LAYER_BASE, + tab.getPosition()); + } + }); for (int i = 0; i < PlatformPagerAdapter.TAB_ICONS.length; i++) { - mTabLayout.getTabAt(i).setIcon(PlatformPagerAdapter.TAB_ICONS[i]); + mBinding.tabsPlatforms.getTabAt(i).setIcon(PlatformPagerAdapter.TAB_ICONS[i]); } - mViewPager.setCurrentItem(IntSetting.MAIN_LAST_PLATFORM_TAB.getIntGlobal()); + mBinding.pagerPlatforms.setCurrentItem(IntSetting.MAIN_LAST_PLATFORM_TAB.getIntGlobal()); showGames(); GameFileCacheManager.startLoad(); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java index 32db29e802..925c755880 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java @@ -23,6 +23,7 @@ import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.activities.EmulationActivity; import org.dolphinemu.dolphinemu.adapters.GameRowPresenter; import org.dolphinemu.dolphinemu.adapters.SettingsRowPresenter; +import org.dolphinemu.dolphinemu.databinding.ActivityTvMainBinding; import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag; import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivity; import org.dolphinemu.dolphinemu.model.GameFile; @@ -50,6 +51,8 @@ public final class TvMainActivity extends FragmentActivity private final ArrayList<ArrayObjectAdapter> mGameRows = new ArrayList<>(); + private ActivityTvMainBinding mBinding; + @Override protected void onCreate(Bundle savedInstanceState) { @@ -58,7 +61,8 @@ public final class TvMainActivity extends FragmentActivity () -> !DirectoryInitialization.areDolphinDirectoriesReady()); super.onCreate(savedInstanceState); - setContentView(R.layout.activity_tv_main); + mBinding = ActivityTvMainBinding.inflate(getLayoutInflater()); + setContentView(mBinding.getRoot()); setupUI(); @@ -118,7 +122,7 @@ public final class TvMainActivity extends FragmentActivity void setupUI() { - mSwipeRefresh = findViewById(R.id.swipe_refresh); + mSwipeRefresh = mBinding.swipeRefresh; mSwipeRefresh.setOnRefreshListener(this); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/platform/PlatformGamesFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/platform/PlatformGamesFragment.java index 62063caaeb..80a7a35fac 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/platform/PlatformGamesFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/platform/PlatformGamesFragment.java @@ -18,6 +18,7 @@ import com.google.android.material.color.MaterialColors; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.adapters.GameAdapter; +import org.dolphinemu.dolphinemu.databinding.FragmentGridBinding; import org.dolphinemu.dolphinemu.services.GameFileCacheManager; import org.dolphinemu.dolphinemu.utils.InsetsHelper; @@ -26,10 +27,11 @@ public final class PlatformGamesFragment extends Fragment implements PlatformGam private static final String ARG_PLATFORM = "platform"; private GameAdapter mAdapter; - private RecyclerView mRecyclerView; private SwipeRefreshLayout mSwipeRefresh; private SwipeRefreshLayout.OnRefreshListener mOnRefreshListener; + private FragmentGridBinding mBinding; + public static PlatformGamesFragment newInstance(Platform platform) { PlatformGamesFragment fragment = new PlatformGamesFragment(); @@ -47,19 +49,20 @@ public final class PlatformGamesFragment extends Fragment implements PlatformGam super.onCreate(savedInstanceState); } + @NonNull @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_grid, container, false); - - findViews(rootView); - - return rootView; + mBinding = FragmentGridBinding.inflate(inflater, container, false); + return mBinding.getRoot(); } @Override public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { + mSwipeRefresh = mBinding.swipeRefresh; + int columns = getResources().getInteger(R.integer.game_grid_columns); RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), columns); mAdapter = new GameAdapter(); @@ -72,10 +75,10 @@ public final class PlatformGamesFragment extends Fragment implements PlatformGam mSwipeRefresh.setOnRefreshListener(mOnRefreshListener); - mRecyclerView.setLayoutManager(layoutManager); - mRecyclerView.setAdapter(mAdapter); + mBinding.gridGames.setLayoutManager(layoutManager); + mBinding.gridGames.setAdapter(mAdapter); - InsetsHelper.setUpList(getContext(), mRecyclerView); + InsetsHelper.setUpList(getContext(), mBinding.gridGames); setRefreshing(GameFileCacheManager.isLoadingOrRescanning()); @@ -83,6 +86,13 @@ public final class PlatformGamesFragment extends Fragment implements PlatformGam } @Override + public void onDestroyView() + { + super.onDestroyView(); + mBinding = null; + } + + @Override public void refreshScreenshotAtPosition(int position) { mAdapter.notifyItemChanged(position); @@ -115,17 +125,13 @@ public final class PlatformGamesFragment extends Fragment implements PlatformGam mOnRefreshListener = listener; if (mSwipeRefresh != null) + { mSwipeRefresh.setOnRefreshListener(listener); + } } public void setRefreshing(boolean refreshing) { - mSwipeRefresh.setRefreshing(refreshing); - } - - private void findViews(View root) - { - mSwipeRefresh = root.findViewById(R.id.swipe_refresh); - mRecyclerView = root.findViewById(R.id.grid_games); + mBinding.swipeRefresh.setRefreshing(refreshing); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/GlideUtils.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/GlideUtils.java index f3a626bebd..0ddf4d44f8 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/GlideUtils.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/GlideUtils.java @@ -23,9 +23,9 @@ import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.transition.Transition; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.adapters.GameAdapter; import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting; import org.dolphinemu.dolphinemu.model.GameFile; -import org.dolphinemu.dolphinemu.viewholders.GameViewHolder; import java.io.File; import java.io.FileNotFoundException; @@ -60,21 +60,21 @@ public class GlideUtils } } - public static void loadGameCover(GameViewHolder gameViewHolder, ImageView imageView, + public static void loadGameCover(GameAdapter.GameViewHolder gameViewHolder, ImageView imageView, GameFile gameFile) { if (BooleanSetting.MAIN_SHOW_GAME_TITLES.getBooleanGlobal() && gameViewHolder != null) { - gameViewHolder.textGameTitle.setText(gameFile.getTitle()); - gameViewHolder.textGameTitle.setVisibility(View.VISIBLE); - gameViewHolder.textGameTitleInner.setVisibility(View.GONE); - gameViewHolder.textGameCaption.setVisibility(View.VISIBLE); + gameViewHolder.binding.textGameTitle.setText(gameFile.getTitle()); + gameViewHolder.binding.textGameTitle.setVisibility(View.VISIBLE); + gameViewHolder.binding.textGameTitleInner.setVisibility(View.GONE); + gameViewHolder.binding.textGameCaption.setVisibility(View.VISIBLE); } else if (gameViewHolder != null) { - gameViewHolder.textGameTitleInner.setText(gameFile.getTitle()); - gameViewHolder.textGameTitle.setVisibility(View.GONE); - gameViewHolder.textGameCaption.setVisibility(View.GONE); + gameViewHolder.binding.textGameTitleInner.setText(gameFile.getTitle()); + gameViewHolder.binding.textGameTitle.setVisibility(View.GONE); + gameViewHolder.binding.textGameCaption.setVisibility(View.GONE); } String customCoverPath = gameFile.getCustomCoverPath(); @@ -198,7 +198,8 @@ public class GlideUtils } } - private static void enableInnerTitle(GameViewHolder gameViewHolder, ImageView imageView) + private static void enableInnerTitle(GameAdapter.GameViewHolder gameViewHolder, + ImageView imageView) { Glide.with(imageView.getContext()) .load(R.drawable.no_banner) @@ -206,15 +207,15 @@ public class GlideUtils if (gameViewHolder != null && !BooleanSetting.MAIN_SHOW_GAME_TITLES.getBooleanGlobal()) { - gameViewHolder.textGameTitleInner.setVisibility(View.VISIBLE); + gameViewHolder.binding.textGameTitleInner.setVisibility(View.VISIBLE); } } - private static void disableInnerTitle(GameViewHolder gameViewHolder) + private static void disableInnerTitle(GameAdapter.GameViewHolder gameViewHolder) { if (gameViewHolder != null && !BooleanSetting.MAIN_SHOW_GAME_TITLES.getBooleanGlobal()) { - gameViewHolder.textGameTitleInner.setVisibility(View.GONE); + gameViewHolder.binding.textGameTitleInner.setVisibility(View.GONE); } } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/GameViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/GameViewHolder.java deleted file mode 100644 index b829847488..0000000000 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/GameViewHolder.java +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -package org.dolphinemu.dolphinemu.viewholders; - -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.recyclerview.widget.RecyclerView; - -import org.dolphinemu.dolphinemu.R; -import org.dolphinemu.dolphinemu.model.GameFile; - -/** - * A simple class that stores references to views so that the GameAdapter doesn't need to - * keep calling findViewById(), which is expensive. - */ -public class GameViewHolder extends RecyclerView.ViewHolder -{ - public ImageView imageScreenshot; - public TextView textGameTitle; - public TextView textGameTitleInner; - public TextView textGameCaption; - - public GameFile gameFile; - - public GameViewHolder(View itemView) - { - super(itemView); - - itemView.setTag(this); - - imageScreenshot = itemView.findViewById(R.id.image_game_screen); - textGameTitle = itemView.findViewById(R.id.text_game_title); - textGameTitleInner = itemView.findViewById(R.id.text_game_title_inner); - textGameCaption = itemView.findViewById(R.id.text_game_caption); - } -} |
