Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to ViewPager2 #2873

Merged
merged 17 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:versionCode="106"
android:versionName="2.55">
android:versionName="2.56">

<uses-permission android:name="android.permission.NFC"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Expand Down
3 changes: 1 addition & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ dependencies {
implementation 'com.google.firebase:firebase-messaging:21.1.0'
implementation 'com.google.firebase:firebase-crashlytics:17.2.1'
implementation 'androidx.legacy:legacy-support-core-ui:1.0.0'
implementation (name: 'rtl-viewpager-2.0.0', ext: 'aar')
implementation('com.github.bumptech.glide:glide:4.9.0') {
exclude group: 'com.android.support'
}
Expand Down Expand Up @@ -461,7 +460,7 @@ android {
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg'
testProguardFiles 'test-proguard.cfg'

multiDexKeepProguard file('proguard-multidex.pro')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Multidex configuration needs to be properly set up

The codebase has multiDexKeepProguard configured but is missing essential multidex setup:

  • The proguard-multidex.pro file is missing
  • No multidex dependency is included
  • No explicit multiDexEnabled configuration

To handle method count in release builds, please:

  1. Add the multidex dependency
  2. Enable multidex in defaultConfig
  3. Create the missing proguard-multidex.pro file with proper keep rules
🔗 Analysis chain

Verify multidex configuration for release builds

Since you're adding multidex ProGuard configuration, ensure that multidex is properly enabled for release builds to handle the method count.

Consider adding explicit multidex configuration in your defaultConfig or release buildType if not already present:

android {
    defaultConfig {
+        multiDexEnabled true
    }
}
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for multidex configuration
rg -i "multiDexEnabled" app/build.gradle

Length of output: 40


Script:

#!/bin/bash
# Let's check the entire build.gradle content to understand the configuration better
cat app/build.gradle

# Also check for multidex-related dependencies
rg -i "multidex" app/build.gradle

Length of output: 25477


Script:

#!/bin/bash
# Let's check if there's a proguard-multidex.pro file and its contents
cat proguard-multidex.pro 2>/dev/null || echo "File not found"

# Also check for any multidex-related dependencies
rg -i "implementation.*multidex" app/build.gradle

Length of output: 118


💡 Codebase verification

🛠️ Refactor suggestion

Missing ProGuard configuration file referenced in build.gradle

The build configuration references a non-existent ProGuard configuration file proguard-multidex.pro. This file is required for the multiDexKeepProguard configuration to work properly, and its absence could lead to issues in release builds, especially with ViewPager2 integration.

  • The referenced file proguard-multidex.pro is missing from the project
  • No alternative ProGuard configuration files were found in standard locations
  • ViewPager2-specific ProGuard rules are not defined anywhere in the project
🔗 Analysis chain

Verify the ProGuard configuration for ViewPager2

The addition of multiDexKeepProguard configuration is appropriate for handling method count limitations in release builds. However, ensure that the proguard-multidex.pro file includes the necessary keep rules for ViewPager2 to prevent any ProGuard-related issues.

Consider adding these ViewPager2-specific ProGuard rules to proguard-multidex.pro if not already present:

# Add to proguard-multidex.pro
+-keep class androidx.viewpager2.widget.ViewPager2 { *; }
+-keepclassmembers class androidx.viewpager2.widget.ViewPager2$** { *; }

Let me verify if there are any other ProGuard configuration files in the project that might contain the ViewPager2 rules.


Let me check for any ProGuard configuration files with different extensions and also look for the main ProGuard configuration in the standard Android project locations.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if proguard-multidex.pro exists and contains ViewPager2 rules
if [ -f "proguard-multidex.pro" ]; then
    echo "Checking proguard-multidex.pro for ViewPager2 rules..."
    rg -i "viewpager2" proguard-multidex.pro
else
    echo "proguard-multidex.pro file not found"
fi

Length of output: 117


Script:

#!/bin/bash
# Search for any ProGuard configuration files
echo "Searching for ProGuard configuration files..."
fd -e pro

# Search for ViewPager2 related rules in any text file
echo -e "\nSearching for ViewPager2 ProGuard rules in any file..."
rg -i "viewpager2.*keep" 

Length of output: 264


Script:

#!/bin/bash
# Search for ProGuard configurations with various extensions
echo "Searching for ProGuard configuration files..."
fd -e proguard
fd -e pro
fd -e txt -x grep -l "proguard" {}

# Check standard Android ProGuard locations
echo -e "\nChecking standard ProGuard locations..."
for file in proguard-rules.pro proguard.pro app/proguard-rules.pro app/proguard.pro; do
    if [ -f "$file" ]; then
        echo "Found: $file"
        echo "Contents:"
        cat "$file"
    fi
done

Length of output: 729

// enable crashlytics
buildConfigField 'boolean', 'USE_CRASHLYTICS', 'true'
ext.enableCrashlytics = true
Expand Down
Binary file removed app/libs/rtl-viewpager-2.0.0.aar
Binary file not shown.
40 changes: 0 additions & 40 deletions app/res/drawable/title_case_tab_vertical.xml

This file was deleted.

45 changes: 0 additions & 45 deletions app/res/drawable/title_neutral_tab_vertical.xml

This file was deleted.

47 changes: 23 additions & 24 deletions app/res/layout/tabbed_detail_view.xml
Original file line number Diff line number Diff line change
@@ -1,41 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:viewBindingIgnore="true">

<LinearLayout
android:id="@+id/tabbed_detail_menu"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>

<LinearLayout
android:id="@+id/tabbed_detail_pager_wrapper"
android:layout_below="@id/tabbed_detail_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="match_parent"
android:orientation="vertical">

<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_gravity="top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/cc_brand_bg"
android:paddingTop="@dimen/dp6"
app:tabMode="scrollable"
app:tabGravity="center"
app:tabIndicatorGravity="bottom"
app:tabIndicatorHeight="2dp"
app:tabIndicatorColor="@color/cc_brand_text"
app:tabPaddingStart="24dp"
app:tabPaddingEnd="24dp"
app:tabTextAppearance="@style/DetailViewTabStyle" />

<!-- NOTE: In order to deal with annoying issues of multiplicity,
this ID shouldn't be considered static for layouts, etc. DO NOT REFER
to the tabbed_detail_pager ID in any xml, and only within the pager
class in android until its ID changes. -->
<com.duolingo.open.rtlviewpager.RtlViewPager
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/tabbed_detail_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<androidx.viewpager.widget.PagerTabStrip
android:id="@+id/pager_tab_strip"
android:layout_gravity="top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/content_min_margin"
android:paddingBottom="@dimen/content_min_margin"
android:textColor="@color/cc_brand_text"
android:background="@color/cc_brand_bg"
/>
</com.duolingo.open.rtlviewpager.RtlViewPager>

android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>

</merge>
4 changes: 4 additions & 0 deletions app/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -343,4 +343,8 @@
<item name="textColor">@color/cc_brand_color</item>
</style>

<style name="DetailViewTabStyle">
<item name="android:textColor">@color/cc_brand_text</item>
</style>

</resources>
1 change: 0 additions & 1 deletion app/src/org/commcare/activities/EntityDetailActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ public void onCreateSessionSafe(Bundle savedInstanceState) {
mDetailView.setRoot(container.findViewById(R.id.entity_detail_tabs));
mDetailView.refresh(detail, mTreeReference, detailIndex);

mDetailView.showMenu();
isFinalSwipeActionEnabled = DeveloperPreferences.isDetailTabSwipeActionEnabled();
}

Expand Down
1 change: 0 additions & 1 deletion app/src/org/commcare/activities/EntitySelectActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,6 @@ private void displayReferenceAwesome(final TreeReference selection, int detailIn

Detail detail = session.getDetail(selectedIntent.getStringExtra(EntityDetailActivity.DETAIL_ID));
factory = new NodeEntityFactory(detail, session.getEvaluationContext(new AndroidInstanceInitializer(session)));
detailView.showMenu();

if (detail.isCompound()) {
// border around right panel doesn't look right when there are tabs
Expand Down
34 changes: 14 additions & 20 deletions app/src/org/commcare/adapters/EntityDetailPagerAdapter.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package org.commcare.adapters;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;

import org.commcare.CommCareApplication;
import org.commcare.cases.entity.EntityUtil;
Expand All @@ -18,30 +21,28 @@
*
* @author jschweers
*/
public class EntityDetailPagerAdapter extends FragmentStatePagerAdapter {
public class EntityDetailPagerAdapter extends FragmentStateAdapter{

private ListItemViewModifier modifier;
private final ListItemViewModifier modifier;
private final Detail detail;
private final int detailIndex;
private final TreeReference mEntityReference;
private final Detail[] displayableChildDetails;

public EntityDetailPagerAdapter(FragmentManager fm, Detail detail, int detailIndex,
TreeReference reference, ListItemViewModifier modifier) {
super(fm);
public EntityDetailPagerAdapter(@NonNull FragmentManager fm, @NonNull Lifecycle lifecycle, Detail detail, int detailIndex, TreeReference reference, ListItemViewModifier modifier) {
super(fm, lifecycle);
this.detail = detail;
this.detailIndex = detailIndex;
this.mEntityReference = reference;
this.modifier = modifier;
this.displayableChildDetails = detail.getDisplayableChildDetails(
EntityUtil.prepareCompoundEvaluationContext(mEntityReference, detail,
CommCareApplication.instance().getCurrentSessionWrapper().getEvaluationContext()));
this.displayableChildDetails = detail.getDisplayableChildDetails(EntityUtil.prepareCompoundEvaluationContext(mEntityReference, detail, CommCareApplication.instance().getCurrentSessionWrapper().getEvaluationContext()));
}

@NonNull
@Override
public Fragment getItem(int i) {
public Fragment createFragment(int position) {
EntityDetailFragment fragment;
if (detail.getNodeset() != null || (detail.isCompound() && displayableChildDetails[i].getNodeset() != null)) {
if (detail.getNodeset() != null || (detail.isCompound() && displayableChildDetails[position].getNodeset() != null)) {
fragment = new EntitySubnodeDetailFragment();
} else {
fragment = new EntityDetailFragment();
Expand All @@ -50,7 +51,7 @@ public Fragment getItem(int i) {
Bundle args = new Bundle();
args.putString(EntityDetailFragment.DETAIL_ID, detail.getId());
if (detail.isCompound()) {
args.putInt(EntityDetailFragment.CHILD_DETAIL_INDEX, i);
args.putInt(EntityDetailFragment.CHILD_DETAIL_INDEX, position);
}
args.putInt(EntityDetailFragment.DETAIL_INDEX, detailIndex);
SerializationUtil.serializeToBundle(args, EntityDetailFragment.CHILD_REFERENCE, mEntityReference);
Expand All @@ -59,14 +60,7 @@ public Fragment getItem(int i) {
}

@Override
public CharSequence getPageTitle(int position) {
Detail detailShowing = detail.isCompound() ? displayableChildDetails[position] : detail;
return detailShowing.getTitle().getText().evaluate();
}

@Override
public int getCount() {
public int getItemCount() {
return detail.isCompound() ? displayableChildDetails.length : 1;
}

}
1 change: 0 additions & 1 deletion app/src/org/commcare/fragments/BreadcrumbBarFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,6 @@ public void expandInlineTile(AppCompatActivity activity, View holder,
CommCareSession session = asw.getSession();

Detail detail = session.getDetail(inlineDetailId);
mInternalDetailView.showMenu();
mInternalDetailView.refresh(detail, tileData.second, 0);
}
expand(activity, holder.findViewById(R.id.com_tile_holder_detail_master));
Expand Down
Loading
Loading