mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	citra_android: Implement edge-to-edge (#6349)
This commit is contained in:
		
							parent
							
								
									8d563d37b4
								
							
						
					
					
						commit
						343717e683
					
				
					 19 changed files with 280 additions and 87 deletions
				
			
		|  | @ -11,7 +11,6 @@ import android.widget.TextView; | |||
| 
 | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.appcompat.app.AlertDialog; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.lifecycle.ViewModelProvider; | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,6 +7,9 @@ import android.view.ViewGroup; | |||
| 
 | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.core.graphics.Insets; | ||||
| import androidx.core.view.ViewCompat; | ||||
| import androidx.core.view.WindowInsetsCompat; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.lifecycle.ViewModelProvider; | ||||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
|  | @ -19,6 +22,9 @@ import org.citra.citra_emu.features.cheats.model.CheatsViewModel; | |||
| import org.citra.citra_emu.ui.DividerItemDecoration; | ||||
| 
 | ||||
| public class CheatListFragment extends Fragment { | ||||
|     private RecyclerView mRecyclerView; | ||||
|     private FloatingActionButton mFab; | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, | ||||
|  | @ -28,19 +34,38 @@ public class CheatListFragment extends Fragment { | |||
| 
 | ||||
|     @Override | ||||
|     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { | ||||
|         RecyclerView recyclerView = view.findViewById(R.id.cheat_list); | ||||
|         FloatingActionButton fab = view.findViewById(R.id.fab); | ||||
|         mRecyclerView = view.findViewById(R.id.cheat_list); | ||||
|         mFab = view.findViewById(R.id.fab); | ||||
| 
 | ||||
|         CheatsActivity activity = (CheatsActivity) requireActivity(); | ||||
|         CheatsViewModel viewModel = new ViewModelProvider(activity).get(CheatsViewModel.class); | ||||
| 
 | ||||
|         recyclerView.setAdapter(new CheatsAdapter(activity, viewModel)); | ||||
|         recyclerView.setLayoutManager(new LinearLayoutManager(activity)); | ||||
|         recyclerView.addItemDecoration(new DividerItemDecoration(activity, null)); | ||||
|         mRecyclerView.setAdapter(new CheatsAdapter(activity, viewModel)); | ||||
|         mRecyclerView.setLayoutManager(new LinearLayoutManager(activity)); | ||||
|         mRecyclerView.addItemDecoration(new DividerItemDecoration(activity, null)); | ||||
| 
 | ||||
|         fab.setOnClickListener(v -> { | ||||
|         mFab.setOnClickListener(v -> { | ||||
|             viewModel.startAddingCheat(); | ||||
|             viewModel.openDetailsView(); | ||||
|         }); | ||||
| 
 | ||||
|         setInsets(); | ||||
|     } | ||||
| 
 | ||||
|     private void setInsets() { | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(mRecyclerView, (v, windowInsets) -> { | ||||
|             Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); | ||||
|             v.setPadding(0, 0, 0, insets.bottom + getResources().getDimensionPixelSize(R.dimen.spacing_fab_list)); | ||||
| 
 | ||||
|             ViewGroup.MarginLayoutParams mlpFab = | ||||
|                     (ViewGroup.MarginLayoutParams) mFab.getLayoutParams(); | ||||
|             int fabPadding = getResources().getDimensionPixelSize(R.dimen.spacing_large); | ||||
|             mlpFab.leftMargin = insets.left + fabPadding; | ||||
|             mlpFab.bottomMargin = insets.bottom + fabPadding; | ||||
|             mlpFab.rightMargin = insets.right + fabPadding; | ||||
|             mFab.setLayoutParams(mlpFab); | ||||
| 
 | ||||
|             return windowInsets; | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -10,18 +10,26 @@ import android.view.ViewGroup; | |||
| 
 | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.appcompat.app.AppCompatActivity; | ||||
| import androidx.core.graphics.Insets; | ||||
| import androidx.core.view.ViewCompat; | ||||
| import androidx.core.view.WindowCompat; | ||||
| import androidx.core.view.WindowInsetsAnimationCompat; | ||||
| import androidx.core.view.WindowInsetsCompat; | ||||
| import androidx.lifecycle.ViewModelProvider; | ||||
| import androidx.slidingpanelayout.widget.SlidingPaneLayout; | ||||
| 
 | ||||
| import com.google.android.material.appbar.AppBarLayout; | ||||
| import com.google.android.material.appbar.MaterialToolbar; | ||||
| 
 | ||||
| import org.citra.citra_emu.R; | ||||
| import org.citra.citra_emu.features.cheats.model.Cheat; | ||||
| import org.citra.citra_emu.features.cheats.model.CheatsViewModel; | ||||
| import org.citra.citra_emu.ui.TwoPaneOnBackPressedCallback; | ||||
| import org.citra.citra_emu.utils.InsetsHelper; | ||||
| import org.citra.citra_emu.utils.ThemeUtil; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class CheatsActivity extends AppCompatActivity | ||||
|         implements SlidingPaneLayout.PanelSlideListener { | ||||
|     private CheatsViewModel mViewModel; | ||||
|  | @ -44,14 +52,16 @@ public class CheatsActivity extends AppCompatActivity | |||
| 
 | ||||
|         super.onCreate(savedInstanceState); | ||||
| 
 | ||||
|         WindowCompat.setDecorFitsSystemWindows(getWindow(), false); | ||||
| 
 | ||||
|         mViewModel = new ViewModelProvider(this).get(CheatsViewModel.class); | ||||
|         mViewModel.load(); | ||||
| 
 | ||||
|         setContentView(R.layout.activity_cheats); | ||||
| 
 | ||||
|         mSlidingPaneLayout = findViewById(R.id.sliding_pane_layout); | ||||
|         mCheatList = findViewById(R.id.cheat_list); | ||||
|         mCheatDetails = findViewById(R.id.cheat_details); | ||||
|         mCheatList = findViewById(R.id.cheat_list_container); | ||||
|         mCheatDetails = findViewById(R.id.cheat_details_container); | ||||
| 
 | ||||
|         mCheatListLastFocus = mCheatList; | ||||
|         mCheatDetailsLastFocus = mCheatDetails; | ||||
|  | @ -71,6 +81,8 @@ public class CheatsActivity extends AppCompatActivity | |||
|         MaterialToolbar toolbar = findViewById(R.id.toolbar_cheats); | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
| 
 | ||||
|         setInsets(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -153,8 +165,7 @@ public class CheatsActivity extends AppCompatActivity | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void setOnFocusChangeListenerRecursively(@NonNull View view, | ||||
|                                                            View.OnFocusChangeListener listener) { | ||||
|     public static void setOnFocusChangeListenerRecursively(@NonNull View view, View.OnFocusChangeListener listener) { | ||||
|         view.setOnFocusChangeListener(listener); | ||||
| 
 | ||||
|         if (view instanceof ViewGroup) { | ||||
|  | @ -165,4 +176,56 @@ public class CheatsActivity extends AppCompatActivity | |||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void setInsets() { | ||||
|         AppBarLayout appBarLayout = findViewById(R.id.appbar_cheats); | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(mSlidingPaneLayout, (v, windowInsets) -> { | ||||
|             Insets barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); | ||||
|             Insets keyboardInsets = windowInsets.getInsets(WindowInsetsCompat.Type.ime()); | ||||
| 
 | ||||
|             InsetsHelper.insetAppBar(barInsets, appBarLayout); | ||||
|             mSlidingPaneLayout.setPadding(barInsets.left, 0, barInsets.right, 0); | ||||
| 
 | ||||
|             // Set keyboard insets if the system supports smooth keyboard animations | ||||
|             ViewGroup.MarginLayoutParams mlpDetails = | ||||
|                     (ViewGroup.MarginLayoutParams) mCheatDetails.getLayoutParams(); | ||||
|             if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R) { | ||||
|                 if (keyboardInsets.bottom > 0) { | ||||
|                     mlpDetails.bottomMargin = keyboardInsets.bottom; | ||||
|                 } else { | ||||
|                     mlpDetails.bottomMargin = barInsets.bottom; | ||||
|                 } | ||||
|             } else { | ||||
|                 if (mlpDetails.bottomMargin == 0) { | ||||
|                     mlpDetails.bottomMargin = barInsets.bottom; | ||||
|                 } | ||||
|             } | ||||
|             mCheatDetails.setLayoutParams(mlpDetails); | ||||
| 
 | ||||
|             return windowInsets; | ||||
|         }); | ||||
| 
 | ||||
|         // Update the layout for every frame that the keyboard animates in | ||||
|         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { | ||||
|             ViewCompat.setWindowInsetsAnimationCallback(mCheatDetails, | ||||
|                     new WindowInsetsAnimationCompat.Callback( | ||||
|                             WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_STOP) { | ||||
|                         int keyboardInsets = 0; | ||||
|                         int barInsets = 0; | ||||
| 
 | ||||
|                         @NonNull | ||||
|                         @Override | ||||
|                         public WindowInsetsCompat onProgress(@NonNull WindowInsetsCompat insets, | ||||
|                                                              @NonNull List<WindowInsetsAnimationCompat> runningAnimations) { | ||||
|                             ViewGroup.MarginLayoutParams mlpDetails = | ||||
|                                     (ViewGroup.MarginLayoutParams) mCheatDetails.getLayoutParams(); | ||||
|                             keyboardInsets = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom; | ||||
|                             barInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom; | ||||
|                             mlpDetails.bottomMargin = Math.max(keyboardInsets, barInsets); | ||||
|                             mCheatDetails.setLayoutParams(mlpDetails); | ||||
|                             return insets; | ||||
|                         } | ||||
|                     }); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -8,13 +8,19 @@ import android.os.Bundle; | |||
| import android.provider.Settings; | ||||
| import android.view.Menu; | ||||
| import android.view.MenuInflater; | ||||
| import android.widget.FrameLayout; | ||||
| import android.widget.Toast; | ||||
| 
 | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.appcompat.app.AppCompatActivity; | ||||
| import androidx.core.graphics.Insets; | ||||
| import androidx.core.view.ViewCompat; | ||||
| import androidx.core.view.WindowCompat; | ||||
| import androidx.core.view.WindowInsetsCompat; | ||||
| import androidx.fragment.app.FragmentTransaction; | ||||
| import androidx.localbroadcastmanager.content.LocalBroadcastManager; | ||||
| 
 | ||||
| import com.google.android.material.appbar.AppBarLayout; | ||||
| import com.google.android.material.appbar.MaterialToolbar; | ||||
| 
 | ||||
| import org.citra.citra_emu.NativeLibrary; | ||||
|  | @ -22,6 +28,7 @@ import org.citra.citra_emu.R; | |||
| import org.citra.citra_emu.utils.DirectoryInitialization; | ||||
| import org.citra.citra_emu.utils.DirectoryStateReceiver; | ||||
| import org.citra.citra_emu.utils.EmulationMenuSettings; | ||||
| import org.citra.citra_emu.utils.InsetsHelper; | ||||
| import org.citra.citra_emu.utils.ThemeUtil; | ||||
| 
 | ||||
| public final class SettingsActivity extends AppCompatActivity implements SettingsActivityView { | ||||
|  | @ -44,9 +51,10 @@ public final class SettingsActivity extends AppCompatActivity implements Setting | |||
|         ThemeUtil.applyTheme(this); | ||||
| 
 | ||||
|         super.onCreate(savedInstanceState); | ||||
| 
 | ||||
|         setContentView(R.layout.activity_settings); | ||||
| 
 | ||||
|         WindowCompat.setDecorFitsSystemWindows(getWindow(), false); | ||||
| 
 | ||||
|         Intent launcher = getIntent(); | ||||
|         String gameID = launcher.getStringExtra(ARG_GAME_ID); | ||||
|         String menuTag = launcher.getStringExtra(ARG_MENU_TAG); | ||||
|  | @ -57,6 +65,8 @@ public final class SettingsActivity extends AppCompatActivity implements Setting | |||
|         MaterialToolbar toolbar = findViewById(R.id.toolbar_settings); | ||||
|         setSupportActionBar(toolbar); | ||||
|         getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
| 
 | ||||
|         setInsets(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -219,4 +229,14 @@ public final class SettingsActivity extends AppCompatActivity implements Setting | |||
|     private SettingsFragment getFragment() { | ||||
|         return (SettingsFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG); | ||||
|     } | ||||
| 
 | ||||
|     private void setInsets() { | ||||
|         AppBarLayout appBar = findViewById(R.id.appbar_settings); | ||||
|         FrameLayout frame = findViewById(R.id.frame_content); | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(frame, (v, windowInsets) -> { | ||||
|             Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); | ||||
|             InsetsHelper.insetAppBar(insets, appBar); | ||||
|             return windowInsets; | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -8,6 +8,9 @@ import android.view.ViewGroup; | |||
| 
 | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.core.graphics.Insets; | ||||
| import androidx.core.view.ViewCompat; | ||||
| import androidx.core.view.WindowInsetsCompat; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | @ -29,6 +32,8 @@ public final class SettingsFragment extends Fragment implements SettingsFragment | |||
| 
 | ||||
|     private SettingsAdapter mAdapter; | ||||
| 
 | ||||
|     private RecyclerView mRecyclerView; | ||||
| 
 | ||||
|     public static Fragment newInstance(String menuTag, String gameId) { | ||||
|         SettingsFragment fragment = new SettingsFragment(); | ||||
| 
 | ||||
|  | @ -71,15 +76,17 @@ public final class SettingsFragment extends Fragment implements SettingsFragment | |||
|     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { | ||||
|         LinearLayoutManager manager = new LinearLayoutManager(getActivity()); | ||||
| 
 | ||||
|         RecyclerView recyclerView = view.findViewById(R.id.list_settings); | ||||
|         mRecyclerView = view.findViewById(R.id.list_settings); | ||||
| 
 | ||||
|         recyclerView.setAdapter(mAdapter); | ||||
|         recyclerView.setLayoutManager(manager); | ||||
|         recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), null)); | ||||
|         mRecyclerView.setAdapter(mAdapter); | ||||
|         mRecyclerView.setLayoutManager(manager); | ||||
|         mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), null)); | ||||
| 
 | ||||
|         SettingsActivityView activity = (SettingsActivityView) getActivity(); | ||||
| 
 | ||||
|         mPresenter.onViewCreated(activity.getSettings()); | ||||
| 
 | ||||
|         setInsets(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -133,4 +140,12 @@ public final class SettingsFragment extends Fragment implements SettingsFragment | |||
|     public void onSettingChanged() { | ||||
|         mActivity.onSettingChanged(); | ||||
|     } | ||||
| 
 | ||||
|     private void setInsets() { | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(mRecyclerView, (v, windowInsets) -> { | ||||
|             Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); | ||||
|             v.setPadding(insets.left, 0, insets.right, insets.bottom); | ||||
|             return windowInsets; | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,48 +0,0 @@ | |||
| package org.citra.citra_emu.features.settings.ui; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import android.util.AttributeSet; | ||||
| import android.widget.FrameLayout; | ||||
| 
 | ||||
| /** | ||||
|  * FrameLayout subclass with few Properties added to simplify animations. | ||||
|  * Don't remove the methods appearing as unused, in order not to break the menu animations | ||||
|  */ | ||||
| public final class SettingsFrameLayout extends FrameLayout { | ||||
|     private float mVisibleness = 1.0f; | ||||
| 
 | ||||
|     public SettingsFrameLayout(Context context) { | ||||
|         super(context); | ||||
|     } | ||||
| 
 | ||||
|     public SettingsFrameLayout(Context context, AttributeSet attrs) { | ||||
|         super(context, attrs); | ||||
|     } | ||||
| 
 | ||||
|     public SettingsFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { | ||||
|         super(context, attrs, defStyleAttr); | ||||
|     } | ||||
| 
 | ||||
|     public SettingsFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { | ||||
|         super(context, attrs, defStyleAttr, defStyleRes); | ||||
|     } | ||||
| 
 | ||||
|     public float getYFraction() { | ||||
|         return getY() / getHeight(); | ||||
|     } | ||||
| 
 | ||||
|     public void setYFraction(float yFraction) { | ||||
|         final int height = getHeight(); | ||||
|         setY((height > 0) ? (yFraction * height) : -9999); | ||||
|     } | ||||
| 
 | ||||
|     public float getVisibleness() { | ||||
|         return mVisibleness; | ||||
|     } | ||||
| 
 | ||||
|     public void setVisibleness(float visibleness) { | ||||
|         setScaleX(visibleness); | ||||
|         setScaleY(visibleness); | ||||
|         setAlpha(visibleness); | ||||
|     } | ||||
| } | ||||
|  | @ -6,6 +6,7 @@ import android.os.Bundle; | |||
| import android.view.Menu; | ||||
| import android.view.MenuInflater; | ||||
| import android.view.MenuItem; | ||||
| import android.widget.FrameLayout; | ||||
| import android.widget.Toast; | ||||
| import androidx.activity.result.ActivityResultLauncher; | ||||
| import androidx.activity.result.contract.ActivityResultContracts; | ||||
|  | @ -15,6 +16,13 @@ import androidx.appcompat.widget.Toolbar; | |||
| import androidx.core.splashscreen.SplashScreen; | ||||
| import com.google.android.material.dialog.MaterialAlertDialogBuilder; | ||||
| import java.util.Collections; | ||||
| import androidx.core.graphics.Insets; | ||||
| import androidx.core.view.ViewCompat; | ||||
| import androidx.core.view.WindowCompat; | ||||
| import androidx.core.view.WindowInsetsCompat; | ||||
| 
 | ||||
| import com.google.android.material.appbar.AppBarLayout; | ||||
| 
 | ||||
| import org.citra.citra_emu.NativeLibrary; | ||||
| import org.citra.citra_emu.R; | ||||
| import org.citra.citra_emu.activities.EmulationActivity; | ||||
|  | @ -27,6 +35,7 @@ import org.citra.citra_emu.utils.BillingManager; | |||
| import org.citra.citra_emu.utils.CitraDirectoryHelper; | ||||
| import org.citra.citra_emu.utils.DirectoryInitialization; | ||||
| import org.citra.citra_emu.utils.FileBrowserHelper; | ||||
| import org.citra.citra_emu.utils.InsetsHelper; | ||||
| import org.citra.citra_emu.utils.PermissionsHandler; | ||||
| import org.citra.citra_emu.utils.PicassoUtils; | ||||
| import org.citra.citra_emu.utils.StartupHandler; | ||||
|  | @ -112,6 +121,8 @@ public final class MainActivity extends AppCompatActivity implements MainView { | |||
|         super.onCreate(savedInstanceState); | ||||
|         setContentView(R.layout.activity_main); | ||||
| 
 | ||||
|         WindowCompat.setDecorFitsSystemWindows(getWindow(), false); | ||||
| 
 | ||||
|         findViews(); | ||||
| 
 | ||||
|         setSupportActionBar(mToolbar); | ||||
|  | @ -136,6 +147,8 @@ public final class MainActivity extends AppCompatActivity implements MainView { | |||
| 
 | ||||
|         // Dismiss previous notifications (should not happen unless a crash occurred) | ||||
|         EmulationActivity.tryDismissRunningNotification(this); | ||||
| 
 | ||||
|         setInsets(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -276,4 +289,15 @@ public final class MainActivity extends AppCompatActivity implements MainView { | |||
|     public static void invokePremiumBilling(Runnable callback) { | ||||
|         mBillingManager.invokePremiumBilling(callback); | ||||
|     } | ||||
| 
 | ||||
|     private void setInsets() { | ||||
|         AppBarLayout appBar = findViewById(R.id.appbar); | ||||
|         FrameLayout frame = findViewById(R.id.games_platform_frame); | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(frame, (v, windowInsets) -> { | ||||
|             Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); | ||||
|             InsetsHelper.insetAppBar(insets, appBar); | ||||
|             frame.setPadding(insets.left, 0, insets.right, 0); | ||||
|             return windowInsets; | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -7,7 +7,9 @@ import android.view.View; | |||
| import android.view.ViewGroup; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import androidx.core.content.ContextCompat; | ||||
| import androidx.core.graphics.Insets; | ||||
| import androidx.core.view.ViewCompat; | ||||
| import androidx.core.view.WindowInsetsCompat; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.recyclerview.widget.GridLayoutManager; | ||||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
|  | @ -68,6 +70,8 @@ public final class PlatformGamesFragment extends Fragment implements PlatformGam | |||
| 
 | ||||
|         pullToRefresh.setProgressBackgroundColorSchemeColor(MaterialColors.getColor(pullToRefresh, R.attr.colorPrimary)); | ||||
|         pullToRefresh.setColorSchemeColors(MaterialColors.getColor(pullToRefresh, R.attr.colorOnPrimary)); | ||||
| 
 | ||||
|         setInsets(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -92,4 +96,12 @@ public final class PlatformGamesFragment extends Fragment implements PlatformGam | |||
|         mRecyclerView = root.findViewById(R.id.grid_games); | ||||
|         mTextView = root.findViewById(R.id.gamelist_empty_text); | ||||
|     } | ||||
| 
 | ||||
|     private void setInsets() { | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(mRecyclerView, (v, windowInsets) -> { | ||||
|             Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); | ||||
|             v.setPadding(0, 0, 0, insets.bottom); | ||||
|             return windowInsets; | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,33 @@ | |||
| package org.citra.citra_emu.utils; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import android.content.res.Resources; | ||||
| import android.view.ViewGroup; | ||||
| 
 | ||||
| import androidx.core.graphics.Insets; | ||||
| 
 | ||||
| import com.google.android.material.appbar.AppBarLayout; | ||||
| 
 | ||||
| public class InsetsHelper { | ||||
|     public static final int THREE_BUTTON_NAVIGATION = 0; | ||||
|     public static final int TWO_BUTTON_NAVIGATION = 1; | ||||
|     public static final int GESTURE_NAVIGATION = 2; | ||||
| 
 | ||||
|     public static void insetAppBar(Insets insets, AppBarLayout appBarLayout) | ||||
|     { | ||||
|         ViewGroup.MarginLayoutParams mlpAppBar = | ||||
|                 (ViewGroup.MarginLayoutParams) appBarLayout.getLayoutParams(); | ||||
|         mlpAppBar.leftMargin = insets.left; | ||||
|         mlpAppBar.rightMargin = insets.right; | ||||
|         appBarLayout.setLayoutParams(mlpAppBar); | ||||
|     } | ||||
| 
 | ||||
|     public static int getSystemGestureType(Context context) { | ||||
|         Resources resources = context.getResources(); | ||||
|         int resourceId = resources.getIdentifier("config_navBarInteractionMode", "integer", "android"); | ||||
|         if (resourceId != 0) { | ||||
|             return resources.getInteger(resourceId); | ||||
|         } | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
|  | @ -1,21 +1,31 @@ | |||
| package org.citra.citra_emu.utils; | ||||
| 
 | ||||
| import android.app.Activity; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.res.Configuration; | ||||
| import android.graphics.Color; | ||||
| import android.os.Build; | ||||
| import android.preference.PreferenceManager; | ||||
| 
 | ||||
| import androidx.annotation.ColorInt; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.appcompat.app.AppCompatActivity; | ||||
| import androidx.appcompat.app.AppCompatDelegate; | ||||
| import androidx.core.content.ContextCompat; | ||||
| import androidx.core.view.WindowCompat; | ||||
| import androidx.core.view.WindowInsetsControllerCompat; | ||||
| 
 | ||||
| import com.google.android.material.color.MaterialColors; | ||||
| 
 | ||||
| import org.citra.citra_emu.CitraApplication; | ||||
| import org.citra.citra_emu.R; | ||||
| import org.citra.citra_emu.features.settings.utils.SettingsFile; | ||||
| 
 | ||||
| public class ThemeUtil { | ||||
|     private static SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(CitraApplication.getAppContext()); | ||||
| 
 | ||||
|     public static final float NAV_BAR_ALPHA = 0.9f; | ||||
| 
 | ||||
|     private static void applyTheme(int designValue, AppCompatActivity activity) { | ||||
|         switch (designValue) { | ||||
|             case 0: | ||||
|  | @ -34,9 +44,40 @@ public class ThemeUtil { | |||
|         int systemReportedThemeMode = activity.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; | ||||
|         WindowInsetsControllerCompat windowController = WindowCompat.getInsetsController(activity.getWindow(), activity.getWindow().getDecorView()); | ||||
|         windowController.setAppearanceLightStatusBars(systemReportedThemeMode == Configuration.UI_MODE_NIGHT_NO); | ||||
|         windowController.setAppearanceLightNavigationBars(systemReportedThemeMode == Configuration.UI_MODE_NIGHT_NO); | ||||
| 
 | ||||
|         setNavigationBarColor(activity, MaterialColors.getColor(activity.getWindow().getDecorView(), R.attr.colorSurface)); | ||||
|     } | ||||
| 
 | ||||
|     public static void applyTheme(AppCompatActivity activity) { | ||||
|         applyTheme(mPreferences.getInt(SettingsFile.KEY_DESIGN, 0), activity); | ||||
|     } | ||||
| 
 | ||||
|     public static void setNavigationBarColor(@NonNull Activity activity, @ColorInt int color) { | ||||
|         int gestureType = InsetsHelper.getSystemGestureType(activity.getApplicationContext()); | ||||
|         int orientation = activity.getResources().getConfiguration().orientation; | ||||
| 
 | ||||
|         // Use a solid color when the navigation bar is on the left/right edge of the screen | ||||
|         if ((gestureType == InsetsHelper.THREE_BUTTON_NAVIGATION || | ||||
|                 gestureType == InsetsHelper.TWO_BUTTON_NAVIGATION) && | ||||
|                 orientation == Configuration.ORIENTATION_LANDSCAPE) { | ||||
|             activity.getWindow().setNavigationBarColor(color); | ||||
|         } else if (gestureType == InsetsHelper.THREE_BUTTON_NAVIGATION || | ||||
|                 gestureType == InsetsHelper.TWO_BUTTON_NAVIGATION) { | ||||
|             // Use semi-transparent color when in portrait mode with three/two button navigation to | ||||
|             // partially see list items behind the navigation bar | ||||
|             activity.getWindow().setNavigationBarColor(ThemeUtil.getColorWithOpacity(color, NAV_BAR_ALPHA)); | ||||
|         } else { | ||||
|             // Use transparent color when using gesture navigation | ||||
|             activity.getWindow().setNavigationBarColor( | ||||
|                     ContextCompat.getColor(activity.getApplicationContext(), | ||||
|                             android.R.color.transparent)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @ColorInt | ||||
|     public static int getColorWithOpacity(@ColorInt int color, float alphaFactor) { | ||||
|         return Color.argb(Math.round(alphaFactor * Color.alpha(color)), Color.red(color), | ||||
|                 Color.green(color), Color.blue(color)); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| <androidx.constraintlayout.widget.ConstraintLayout | ||||
|     xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent"> | ||||
| 
 | ||||
|  | @ -17,14 +18,12 @@ | |||
|             android:id="@+id/appbar_cheats" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
|             app:elevation="0dp" | ||||
|             app:liftOnScroll="false"> | ||||
|             android:fitsSystemWindows="true"> | ||||
| 
 | ||||
|             <com.google.android.material.appbar.MaterialToolbar | ||||
|                 android:id="@+id/toolbar_cheats" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:background="?attr/colorSurface" /> | ||||
|                 android:layout_height="?attr/actionBarSize" /> | ||||
| 
 | ||||
|         </com.google.android.material.appbar.AppBarLayout> | ||||
| 
 | ||||
|  | @ -40,18 +39,20 @@ | |||
|         app:layout_constraintTop_toBottomOf="@id/coordinator_cheats"> | ||||
| 
 | ||||
|         <androidx.fragment.app.FragmentContainerView | ||||
|             android:layout_width="320dp" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" | ||||
|             android:layout_weight="1" | ||||
|             android:id="@+id/cheat_list" | ||||
|             android:name="org.citra.citra_emu.features.cheats.ui.CheatListFragment" /> | ||||
|             android:id="@+id/cheat_list_container" | ||||
|             android:name="org.citra.citra_emu.features.cheats.ui.CheatListFragment" | ||||
|             tools:layout="@layout/fragment_cheat_list" /> | ||||
| 
 | ||||
|         <androidx.fragment.app.FragmentContainerView | ||||
|             android:layout_width="320dp" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" | ||||
|             android:layout_weight="1" | ||||
|             android:id="@+id/cheat_details" | ||||
|             android:name="org.citra.citra_emu.features.cheats.ui.CheatDetailsFragment" /> | ||||
|             android:id="@+id/cheat_details_container" | ||||
|             android:name="org.citra.citra_emu.features.cheats.ui.CheatDetailsFragment" | ||||
|             tools:layout="@layout/fragment_cheat_details" /> | ||||
| 
 | ||||
|     </androidx.slidingpanelayout.widget.SlidingPaneLayout> | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,13 +9,14 @@ | |||
|     <com.google.android.material.appbar.AppBarLayout | ||||
|         android:id="@+id/appbar" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content"> | ||||
|         android:layout_height="wrap_content" | ||||
|         android:fitsSystemWindows="true" | ||||
|         app:liftOnScrollTargetViewId="@id/grid_games"> | ||||
| 
 | ||||
|         <com.google.android.material.appbar.MaterialToolbar | ||||
|             android:id="@+id/toolbar_main" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="?attr/actionBarSize" | ||||
|             android:background="?attr/colorSurface" | ||||
|             app:subtitleTextColor="?attr/colorOnSurface" | ||||
|             app:titleTextColor="?attr/colorOnSurface" /> | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,13 +8,13 @@ | |||
|     <com.google.android.material.appbar.AppBarLayout | ||||
|         android:id="@+id/appbar_settings" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content"> | ||||
|         android:layout_height="wrap_content" | ||||
|         android:fitsSystemWindows="true"> | ||||
| 
 | ||||
|         <com.google.android.material.appbar.MaterialToolbar | ||||
|             android:id="@+id/toolbar_settings" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="?attr/actionBarSize" | ||||
|             android:background="?attr/colorSurface" /> | ||||
|             android:layout_height="?attr/actionBarSize" /> | ||||
| 
 | ||||
|     </com.google.android.material.appbar.AppBarLayout> | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ | |||
|         android:id="@+id/cheat_list" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="0dp" | ||||
|         android:clipToPadding="false" | ||||
|         app:layout_constraintStart_toStartOf="parent" | ||||
|         app:layout_constraintEnd_toEndOf="parent" | ||||
|         app:layout_constraintTop_toTopOf="parent" | ||||
|  | @ -21,7 +22,7 @@ | |||
|         android:src="@drawable/ic_add" | ||||
|         android:contentDescription="@string/cheats_add" | ||||
|         android:layout_margin="16dp" | ||||
|         app:layout_constraintStart_toStartOf="parent" | ||||
|         app:layout_constraintEnd_toEndOf="parent" | ||||
|         app:layout_constraintBottom_toBottomOf="parent" /> | ||||
| 
 | ||||
| </androidx.constraintlayout.widget.ConstraintLayout> | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ | |||
|                 android:id="@+id/grid_games" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="match_parent" | ||||
|                 android:clipToPadding="false" | ||||
|                 tools:listitem="@layout/card_game" /> | ||||
| 
 | ||||
|         </RelativeLayout> | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <org.citra.citra_emu.features.settings.ui.SettingsFrameLayout | ||||
| <FrameLayout | ||||
|     xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:id="@+id/list_settings_root" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     android:background="?attr/colorSurface"> | ||||
|  | @ -8,6 +9,7 @@ | |||
|     <androidx.recyclerview.widget.RecyclerView | ||||
|         android:id="@+id/list_settings" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="match_parent" /> | ||||
|         android:layout_height="match_parent" | ||||
|         android:clipToPadding="false" /> | ||||
| 
 | ||||
| </org.citra.citra_emu.features.settings.ui.SettingsFrameLayout> | ||||
| </FrameLayout> | ||||
|  |  | |||
|  | @ -24,11 +24,12 @@ | |||
| 
 | ||||
|     <CheckBox | ||||
|         android:id="@+id/checkbox" | ||||
|         android:layout_width="48dp" | ||||
|         android:layout_height="64dp" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:focusable="true" | ||||
|         android:gravity="center" | ||||
|         android:nextFocusLeft="@id/root" | ||||
|         android:layout_marginEnd="8dp" | ||||
|         app:layout_constraintBottom_toBottomOf="parent" | ||||
|         app:layout_constraintEnd_toEndOf="parent" | ||||
|         app:layout_constraintStart_toEndOf="@id/text_name" | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
|     <dimen name="spacing_small">4dp</dimen> | ||||
|     <dimen name="spacing_medlarge">12dp</dimen> | ||||
|     <dimen name="spacing_large">16dp</dimen> | ||||
|     <dimen name="spacing_fab_list">80dp</dimen> | ||||
| 
 | ||||
|     <dimen name="dialog_margin">20dp</dimen> | ||||
| </resources> | ||||
|  |  | |||
|  | @ -38,7 +38,8 @@ | |||
|         <item name="colorPrimaryInverse">@color/citra_inversePrimary</item> | ||||
| 
 | ||||
|         <item name="homeAsUpIndicator">@drawable/ic_back</item> | ||||
|         <item name="android:statusBarColor">@color/citra_surface</item> | ||||
|         <item name="android:statusBarColor">@android:color/transparent</item> | ||||
|         <item name="android:navigationBarColor">@android:color/transparent</item> | ||||
|         <item name="android:textColorLink">@color/citra_primary</item> | ||||
|         <item name="materialAlertDialogTheme">@style/CitraMaterialDialog</item> | ||||
|         <item name="popupMenuStyle">@style/CitraShapedPopup</item> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue