From 63da454002b702956a02128cec3ce721240c6519 Mon Sep 17 00:00:00 2001 From: Mas Azalya Date: Mon, 27 Oct 2025 23:33:51 +0800 Subject: [PATCH 1/4] UI fix for Android 15,16 --- .../shimmerServiceExample/build.gradle | 1 + .../shimmercapture/MainActivity.java | 121 ++++++++++++++++++ .../src/main/res/layout/activity_main.xml | 93 ++++---------- .../src/main/res/values/attrs.xml | 5 + .../src/main/res/values/dimens.xml | 1 + .../src/main/res/values/styles.xml | 12 +- 6 files changed, 166 insertions(+), 67 deletions(-) create mode 100644 ShimmerAndroidInstrumentDriver/shimmerServiceExample/src/main/res/values/attrs.xml diff --git a/ShimmerAndroidInstrumentDriver/shimmerServiceExample/build.gradle b/ShimmerAndroidInstrumentDriver/shimmerServiceExample/build.gradle index 3224bd20..2b6f599a 100644 --- a/ShimmerAndroidInstrumentDriver/shimmerServiceExample/build.gradle +++ b/ShimmerAndroidInstrumentDriver/shimmerServiceExample/build.gradle @@ -62,4 +62,5 @@ dependencies { implementation 'androidx.multidex:multidex:2.0.1' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + implementation 'com.google.android.material:material:1.12.0' // or latest stable } diff --git a/ShimmerAndroidInstrumentDriver/shimmerServiceExample/src/main/java/com/shimmerresearch/shimmercapture/MainActivity.java b/ShimmerAndroidInstrumentDriver/shimmerServiceExample/src/main/java/com/shimmerresearch/shimmercapture/MainActivity.java index e97edee0..84d402c2 100644 --- a/ShimmerAndroidInstrumentDriver/shimmerServiceExample/src/main/java/com/shimmerresearch/shimmercapture/MainActivity.java +++ b/ShimmerAndroidInstrumentDriver/shimmerServiceExample/src/main/java/com/shimmerresearch/shimmercapture/MainActivity.java @@ -13,8 +13,14 @@ import android.os.Message; import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; +import androidx.core.graphics.Insets; +import androidx.core.graphics.drawable.DrawableCompat; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsCompat; import androidx.fragment.app.FragmentManager; @@ -33,6 +39,7 @@ import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; +import android.view.Gravity; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -40,9 +47,11 @@ import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; +import android.widget.TextView; import android.widget.Toast; import com.androidplot.xy.XYPlot; import com.clj.fastble.BleManager; +import com.google.android.material.tabs.TabLayout; import com.shimmerresearch.android.Shimmer; import com.shimmerresearch.android.Shimmer4Android; import com.shimmerresearch.android.guiUtilities.supportfragments.ConnectedShimmersListFragment; @@ -76,6 +85,7 @@ import com.shimmerresearch.verisense.communication.SyncProgressDetails; import java.io.File; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; @@ -181,7 +191,118 @@ public void requestPermissions(){ startServiceandBTManager(); } + WindowCompat.setDecorFitsSystemWindows(getWindow(), false); setContentView(R.layout.activity_main); + + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + SectionsPagerAdapter1 sectionsPagerAdapter = new SectionsPagerAdapter1(getSupportFragmentManager()); + ViewPager viewPager = findViewById(R.id.container); + viewPager.setAdapter(sectionsPagerAdapter); + + TabLayout tabs = findViewById(R.id.tabs); + tabs.setupWithViewPager(viewPager); +/* +// ✅ Important: use dispatch listener, not consume listener + ViewCompat.setOnApplyWindowInsetsListener(toolbar, (v, insets) -> { + Insets bars = insets.getInsets(WindowInsetsCompat.Type.statusBars()); + + toolbar.postDelayed(() -> { + int topInset = bars.top; + + // Toolbar height should be roughly ?attr/actionBarSize + topInset + int toolbarHeight = toolbar.getHeight(); + + // 🔹 Lower the title slightly, but keep toolbar nicely below the status bar + int targetPaddingTop = (int) (topInset * 0.6f); + int targetPaddingBottom = (int) (toolbarHeight * 0.10f); // add gentle bottom padding + + Log.d("ToolbarAdjust", "Top inset=" + topInset + + ", toolbarHeight=" + toolbarHeight + + ", paddingTop=" + targetPaddingTop + + ", paddingBottom=" + targetPaddingBottom); + + toolbar.setPadding( + toolbar.getPaddingLeft(), + targetPaddingTop, + toolbar.getPaddingRight(), + targetPaddingBottom + ); + }, 100); + + return insets; + }); + + toolbar.post(() -> { + try { + // Access the private TextView that AppCompatToolbar uses for the title + Field f = toolbar.getClass().getDeclaredField("mTitleTextView"); + f.setAccessible(true); + TextView titleTextView = (TextView) f.get(toolbar); + + if (titleTextView != null) { + // Center the title vertically within the toolbar + Toolbar.LayoutParams lp = (Toolbar.LayoutParams) titleTextView.getLayoutParams(); + lp.gravity = Gravity.CENTER_VERTICAL | Gravity.START; + titleTextView.setLayoutParams(lp); + + // Move it slightly lower for better visual centering + titleTextView.setPadding( + titleTextView.getPaddingLeft(), + 20, // increase this (e.g. 12) if still looks too high + titleTextView.getPaddingRight(), + 0 + ); + + Log.d("ToolbarTitleFix", "Adjusted title via reflection"); + } + } catch (Exception e) { + e.printStackTrace(); + } + }); + */ + + // Insets listener — apply a fraction of status bar top as toolbar top padding + ViewCompat.setOnApplyWindowInsetsListener(toolbar, (v, insets) -> { + Insets bars = insets.getInsets(WindowInsetsCompat.Type.statusBars()); + toolbar.post(() -> { + int targetPaddingTop = (int) (bars.top * 0.35f); + toolbar.setPadding(toolbar.getPaddingLeft(), targetPaddingTop, toolbar.getPaddingRight(), toolbar.getPaddingBottom()); + }); + return insets; + }); + + // ✅ Align title and overflow icons consistently + toolbar.post(() -> { + try { + // Center title vertically and slightly lower it + Field f = toolbar.getClass().getDeclaredField("mTitleTextView"); + f.setAccessible(true); + TextView titleTextView = (TextView) f.get(toolbar); + if (titleTextView != null) { + Toolbar.LayoutParams lp = (Toolbar.LayoutParams) titleTextView.getLayoutParams(); + lp.gravity = Gravity.CENTER_VERTICAL | Gravity.START; + titleTextView.setLayoutParams(lp); + // Slight downward offset (adjust 16–22 if needed) + titleTextView.setPadding( + titleTextView.getPaddingLeft(), + 40, + titleTextView.getPaddingRight(), + 0 + ); + } + } catch (Exception ignore) { /* Safe fallback if reflection fails */ } + + // Move the overflow (⋮) menu slightly DOWN for perfect alignment + for (int i = 0; i < toolbar.getChildCount(); i++) { + View child = toolbar.getChildAt(i); + if (child.getClass().getSimpleName().equals("ActionMenuView")) { + child.setTranslationY(30f); // try 4f–6f for best result + } + } + }); + // Create the adapter that will return a fragment for each of the three // primary sections of the activity. mSectionsPagerAdapter1 = new SectionsPagerAdapter1(getSupportFragmentManager()); diff --git a/ShimmerAndroidInstrumentDriver/shimmerServiceExample/src/main/res/layout/activity_main.xml b/ShimmerAndroidInstrumentDriver/shimmerServiceExample/src/main/res/layout/activity_main.xml index cbc2ef82..790f1e89 100644 --- a/ShimmerAndroidInstrumentDriver/shimmerServiceExample/src/main/res/layout/activity_main.xml +++ b/ShimmerAndroidInstrumentDriver/shimmerServiceExample/src/main/res/layout/activity_main.xml @@ -1,75 +1,38 @@ - - + android:layout_width="match_parent" + android:layout_height="match_parent"> - - - -