Linjiajia
2023-10-26 ecaf8069072e71db4bff94671e72764b211d6af1
功能完善
49个文件已修改
14个文件已添加
1 文件已重命名
1个文件已删除
3674 ■■■■ 已修改文件
.idea/deploymentTargetDropDown.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/build.gradle 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/AndroidManifest.xml 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/adapter/ElectronicFileAddAdapter.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/adapter/ExaminationInfoRvAdapter.java 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/bean/AnnualHealthStatusBean.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/bean/ExaminationInfoBean.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/bean/ExaminationInfoRequestBean.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/data/DataRepository.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/data/source/HttpDataSource.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/data/source/http/ApiService.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/data/source/http/HttpDataSourceImpl.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/BrowserActivity.java 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/DLBaseActivity.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/DLBaseFragment.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/PlayerActivity.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/dialog/UpdateDialog.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/dialog/VersionUpdateDialog.java 244 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/AnnualHealthStatusActivity.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/AnnualHealthStatusActivityViewModel.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/AnnualHealthStatusDetailActivity.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/CertificateOfHonorActivityViewModel.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/ExaminationInfoActivity.java 348 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/ExaminationInfoActivityViewModel.java 346 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/ExaminationInfoDetailActivity.java 313 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/ExaminationInfoDetailActivityViewModel.java 361 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/FamilyAssetsActivityViewModel.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/FunctionFragment.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/HealthCareActivity.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/ImageCarouselFragment.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/TourismExperienceActivityViewModel.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/VideoCarouselFragment.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/function/VideoFragment.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/home/HomeFragment.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/ui/main/MainActivity.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/widget/DoubleNode.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/widget/HomeMindMapLayout.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/widget/Node.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/application/zhangshi_app_android/widget/SimpleNode.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/shape_gradient_browser_progress.xml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_annual_health_status.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_annual_health_status_detail.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_browser.xml 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_examination_info.xml 318 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_examination_info_detail.xml 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_growth_experience.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_health_care.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/item_examination_info.xml 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/item_family_member.xml 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/item_tourism.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/layout_drawer.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/pop_annual_health_status.xml 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/pop_basic_information_double.xml 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/pop_operate_exam_info.xml 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/values/strings.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app_base/src/main/java/com/android/app_base/action/TitleBarAction.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app_base/src/main/java/com/android/app_base/base/BaseConfig.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app_base/src/main/java/com/android/app_base/base/adapter/BaseVp2FragmentAdapter.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app_base/src/main/java/com/android/app_base/base/adapter/databinding/ImageViewAdapter.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app_base/src/main/java/com/android/app_base/base/adapter/databinding/TextViewAdapter.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app_base/src/main/java/com/android/app_base/base/view/BaseActivity.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app_base/src/main/java/com/android/app_base/base/viewmodel/BaseViewModel.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app_base/src/main/java/com/android/app_base/http/OkHttpHelper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app_base/src/main/java/com/android/app_base/http/interceptor/AuthInterceptor.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app_base/src/main/java/com/android/app_base/widget/ExtendTitleBar.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/deploymentTargetDropDown.xml
@@ -7,11 +7,11 @@
        <deviceKey>
          <Key>
            <type value="VIRTUAL_DEVICE_PATH" />
            <value value="D:\software\Android\.android\avd\Nexus_6_API_30.avd" />
            <value value="D:\software\Android\.android\avd\Pixel_API_30.avd" />
          </Key>
        </deviceKey>
      </Target>
    </targetSelectedWithDropDown>
    <timeTargetWasSelectedWithDropDown value="2023-10-06T11:49:32.134674900Z" />
    <timeTargetWasSelectedWithDropDown value="2023-10-25T11:40:17.439780100Z" />
  </component>
</project>
app/build.gradle
@@ -8,12 +8,12 @@
        applicationId "com.application.zhangshi_app_android"
        minSdk 24
        targetSdk 33
        versionCode 6
        versionName "1.0.32"
        versionCode 3
        versionName "1.0.2"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        ndk {
            //APP的build.gradle设置支持的SO库架构
            abiFilters 'armeabi', 'armeabi-v7a', 'x86'
            abiFilters 'armeabi', 'armeabi-v7a', 'x86' , 'arm64-v8a', 'x86_64'
        }
    }
    signingConfigs {
app/src/main/AndroidManifest.xml
@@ -86,12 +86,14 @@
        <activity
            android:name=".ui.main.MainActivity"
            android:exported="true"
            android:launchMode="singleTask"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
            />
        <activity
            android:name=".ui.login.LoginActivity"
            android:exported="true"
            android:screenOrientation="portrait">
            android:screenOrientation="portrait"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
@@ -100,133 +102,186 @@
        </activity>
        <activity
            android:name=".ui.function.FamilyMemorabiliaActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.FamilyMemorabiliaDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait"
            />
        <activity
            android:name=".ui.function.FamilyAssetsActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.FamilyAssetsDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.HomeDevicesActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.HomeDevicesDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.GrowthExperienceActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.HonorCollectionDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.HonorCollectionActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.LittleDoctorDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.LittleDoctorActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.CleanStorageActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.CleanStorageDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.IncomeAndExpensesActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.IncomeAndExpensesDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.PropertyActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.PropertyDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.HundredWishActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.HundredWishDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.CertificateOfHonorActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.CertificateOfHonorDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.MarriageActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.PetDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.PetMemoActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.PetMemoDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.HealthCareActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.AnnualHealthStatusActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.AnnualHealthStatusDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.PrivacyActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.PrivacyDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.TourismActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.TourismDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.TourismExperienceActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.TourismExperienceDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.personal_center.BasicInfoActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.ContactsActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.ContactsImportActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.PersonalNotepadActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.PersonalNotepadDetailActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.PetActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.ExaminationInfoActivity"
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.ExaminationInfoDetailActivity"
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity
            android:name=".ui.function.ImageSelectActivity"
            android:exported="false" />
            android:exported="false"
            android:screenOrientation="portrait" />
        <activity android:name=".ui.home.GenealogyActivity"
            android:exported="false"/>
            android:exported="false"
            android:screenOrientation="portrait"/>
        <activity android:name=".ui.personal_center.LoginBgChangeActivity"
            android:exported="false"/>
            android:exported="false"
            android:screenOrientation="portrait"/>
        <activity android:name=".ui.home.HomeMindMapActivity"
            android:exported="false"/>
            android:exported="false"
            android:screenOrientation="portrait"/>
        <!-- 查看大图 -->
        <activity
@@ -255,12 +310,17 @@
            android:theme="@style/FullScreenTheme" />
        <activity
            android:name=".ui.PlayActivity"
            android:name=".ui.PlayerActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
            android:screenOrientation="portrait"
            android:theme="@style/FullScreenTheme"
            />
        <activity
            android:name=".ui.BrowserActivity"
            android:screenOrientation="portrait" />
    </application>
</manifest>
app/src/main/java/com/application/zhangshi_app_android/adapter/ElectronicFileAddAdapter.java
@@ -2,22 +2,21 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.util.Base64;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.util.Pair;
import com.android.app_base.base.BaseConfig;
import com.android.app_base.base.adapter.BaseRVAdapter;
import com.application.zhangshi_app_android.R;
import com.application.zhangshi_app_android.databinding.ItemElectronicFileAddBinding;
import com.application.zhangshi_app_android.ui.BrowserActivity;
import com.application.zhangshi_app_android.ui.ImagePreviewActivity;
import com.application.zhangshi_app_android.ui.PlayActivity;
import com.application.zhangshi_app_android.ui.VideoPlayActivity;
import com.application.zhangshi_app_android.ui.PlayerActivity;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -93,7 +92,6 @@
        if (getItemViewType(position) == TYPE_Add) {
            holder.getBinding().flAdd.setVisibility(View.VISIBLE);
            holder.getBinding().flImage.setVisibility(View.GONE);
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
@@ -109,6 +107,30 @@
            holder.getBinding().flAdd.setVisibility(View.GONE);
            holder.getBinding().flImage.setVisibility(View.VISIBLE);
            String item = mDataList.get(position);
            if (isShowAddItem) {
                holder.getBinding().ivDelete.setVisibility(View.VISIBLE);
            } else {
                holder.getBinding().ivDelete.setVisibility(View.GONE);
            }
            if (isShowDeleteIcon) {
                holder.getBinding().ivDelete.setVisibility(View.VISIBLE);
            } else {
                holder.getBinding().ivDelete.setVisibility(View.GONE);
            }
            if (isShowSelectIcon) {
                holder.getBinding().ivSelect.setVisibility(View.VISIBLE);
                if (selectedItems.contains(item)){
                    holder.getBinding().ivSelect.setBackgroundResource(R.drawable.ic_checked);
                } else {
                    holder.getBinding().ivSelect.setBackgroundResource(R.drawable.ic_unchecked);
                }
            } else {
                holder.getBinding().ivSelect.setVisibility(View.GONE);
            }
            //非预览状态下,点击item 调用 mItemAndAddClickListener.onItemClick
            //预览状态下,点击item 调用 相应的 文件预览
            if (!isPreview){
@@ -120,10 +142,32 @@
                        }
                    }
                });
            }else {
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        String url = mDataList.get(position);
                        if (url.contains("profile/upload")) {//如果是上传到服务器的文件
                            //只取profile/upload以后的部分
                            url = url.substring(url.indexOf("profile/upload"));
                            url = BaseConfig.BASE_URL_DOMAIN + "/" + url;
                            //处理url进行Base64编码,借助 kkfileview 进行文件预览
                            // URL编码Base64编码后的URL
                            try {
                                String encodedUrl = URLEncoder.encode(Base64.encodeToString(url.getBytes(), Base64.NO_WRAP), "UTF-8");
                                String kkFileViewUrl = "https://www.bendudu.com:8085/preview/onlinePreview?url=" + encodedUrl;
                                BrowserActivity.start(mContext, kkFileViewUrl);
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                });
            }
            String item = mDataList.get(position);
            if (item != null) {
                //非图片视频,打开文件预览
                if (item.endsWith(".pdf")) {
                    holder.getBinding().ivImage.setImageResource(R.drawable.ic_pdf);
                } else if (item.endsWith(".zip") || item.endsWith(".aar") || item.endsWith(".7z")) {
@@ -157,8 +201,7 @@
//                                        .setVideoSource(item)
//                                        .setActivityOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
//                                        .start(mContext);
                                PlayActivity.start((Activity) mContext, item,holder.itemView,true);
                                PlayerActivity.startWrapUrl((Activity) mContext, item,holder.itemView,true);
                            }
                        });
                    }
@@ -169,29 +212,6 @@
                } else {
                    holder.getBinding().ivImage.setImageResource(R.drawable.ic_others);
                }
            }
            if (isShowAddItem) {
                holder.getBinding().ivDelete.setVisibility(View.VISIBLE);
            } else {
                holder.getBinding().ivDelete.setVisibility(View.GONE);
            }
            if (isShowDeleteIcon) {
                holder.getBinding().ivDelete.setVisibility(View.VISIBLE);
            } else {
                holder.getBinding().ivDelete.setVisibility(View.GONE);
            }
            if (isShowSelectIcon) {
                holder.getBinding().ivSelect.setVisibility(View.VISIBLE);
                if (selectedItems.contains(item)){
                    holder.getBinding().ivSelect.setBackgroundResource(R.drawable.ic_checked);
                } else {
                    holder.getBinding().ivSelect.setBackgroundResource(R.drawable.ic_unchecked);
                }
            } else {
                holder.getBinding().ivSelect.setVisibility(View.GONE);
            }
        }
app/src/main/java/com/application/zhangshi_app_android/adapter/ExaminationInfoRvAdapter.java
New file
@@ -0,0 +1,167 @@
package com.application.zhangshi_app_android.adapter;
import android.content.Context;
import android.content.Intent;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import androidx.recyclerview.widget.GridLayoutManager;
import com.android.app_base.base.BaseConfig;
import com.android.app_base.base.adapter.BaseRVAdapter;
import com.android.app_base.base.dialog.BaseDialog;
import com.android.app_base.base.dialog.UIDialog;
import com.android.app_base.manager.AppManager;
import com.android.app_base.utils.Utils;
import com.application.zhangshi_app_android.R;
import com.application.zhangshi_app_android.bean.ExaminationInfoBean;
import com.application.zhangshi_app_android.databinding.ItemExaminationInfoBinding;
import com.application.zhangshi_app_android.ui.function.ExaminationInfoDetailActivity;
import com.application.zhangshi_app_android.ui.function.ExaminationInfoActivityViewModel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @author Ljj
 * @date 2023.10.23. 22:11
 * @desc 历年体检报告适配器
 */
public class ExaminationInfoRvAdapter extends BaseRVAdapter<ExaminationInfoBean, ItemExaminationInfoBinding, ExaminationInfoRvAdapter.ViewHolder> {
    private ExaminationInfoActivityViewModel viewModel;
    private final Map<ExaminationInfoBean, Boolean> expendMap = new HashMap<>();
    private boolean isCheckable;
    public ExaminationInfoRvAdapter(Context context, ExaminationInfoActivityViewModel viewModel) {
        super(context);
        this.viewModel = viewModel;
    }
    @Override
    protected int getLayoutId() {
        return R.layout.item_examination_info;
    }
    @Override
    protected ViewHolder getViewHolder(ItemExaminationInfoBinding itemBind, int viewType) {
        return new ViewHolder(itemBind);
    }
    @Override
    protected void onBind(ViewHolder holder, int position) {
        holder.getBinding().setBean(mDataList.get(position));
        if (position % 2 != 0){
            holder.getBinding().cardView.setCardBackgroundColor(mContext.getColor(R.color.color_card_blue));
        }else {
            holder.getBinding().cardView.setCardBackgroundColor(mContext.getColor(R.color.color_card_pink));
        }
        if (!expendMap.containsKey(getItem(position))){
            expendMap.put(getItem(position),false);
        }
        if (Boolean.TRUE.equals(expendMap.get(getItem(position)))){
            holder.getBinding().ivFold.setBackgroundResource(R.drawable.ic_unfold);
            holder.getBinding().cardView.post(() -> {
                holder.getBinding().cardView.getLayoutParams().height = FrameLayout.LayoutParams.WRAP_CONTENT;
                holder.getBinding().cardView.requestLayout();
            });
        }else{
            holder.getBinding().ivFold.setBackgroundResource(R.drawable.ic_fold);
            holder.getBinding().cardView.post(() -> {
                holder.getBinding().cardView.getLayoutParams().height = holder.getBinding().layoutTitle.getMeasuredHeight();
                holder.getBinding().cardView.requestLayout();
            });
        }
        if (isCheckable){
            holder.getBinding().checkbox.setVisibility(View.VISIBLE);
            holder.getBinding().checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (viewModel.getCheckListLiveData().getValue() == null){
                        viewModel.getCheckListLiveData().setValue(new ArrayList<>());
                    }
                    List<ExaminationInfoBean> list = new ArrayList<>(viewModel.getCheckListLiveData().getValue());
                    if (isChecked){
                        if (!list.contains(mDataList.get(position))){
                            list.add(mDataList.get(position));
                        }
                    }else{
                        list.remove(mDataList.get(position));
                    }
                    viewModel.getCheckListLiveData().setValue(list);
                }
            });
            holder.getBinding().checkbox.setChecked(viewModel.getCheckListLiveData().getValue().contains(mDataList.get(position)));
        }else{
            holder.getBinding().checkbox.setVisibility(View.GONE);
        }
        holder.getBinding().layoutTitle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Boolean.TRUE.equals(expendMap.get(getItem(position)))){
                    int initialHeight = holder.getBinding().cardView.getMeasuredHeight();
                    int collapsedHeight = holder.getBinding().layoutTitle.getMeasuredHeight();
                    Utils.pullCollapse(holder.getBinding().cardView,initialHeight,collapsedHeight);
                    holder.getBinding().ivFold.setBackgroundResource(R.drawable.ic_fold);
                    expendMap.put(getItem(position),false);
                }else{
                    final int initialHeight = holder.getBinding().cardView.getMeasuredHeight();
                    holder.getBinding().cardView.measure(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
                    int targetHeight = holder.getBinding().cardView.getMeasuredHeight();
                    Utils.dropExpand(holder.getBinding().cardView,initialHeight,targetHeight);
                    holder.getBinding().ivFold.setBackgroundResource(R.drawable.ic_unfold);
                    expendMap.put(getItem(position),true);
                }
            }
        });
        holder.itemView.setOnClickListener(v -> {
            AppManager.getAppManager().startActivity(
                    new Intent(getRecyclerView().getContext(), ExaminationInfoDetailActivity.class)
                            .putExtra(BaseConfig.EXTRA_TYPE,0)
                            .putExtra("bean",mDataList.get(position)));
        });
        holder.getBinding().layoutModify.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AppManager.getAppManager().startActivity(
                        new Intent(getRecyclerView().getContext(), ExaminationInfoDetailActivity.class)
                                .putExtra(BaseConfig.EXTRA_TYPE,2)
                                .putExtra("bean",mDataList.get(position)));
            }
        });
        holder.getBinding().layoutDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new UIDialog.Builder(mContext)
                        .setTitle("您确定要删除该项目吗")
                        .setContent("项目删除后将无法恢复")
                        .setConfirm("确定")
                        .setCancel("取消")
                        .setListener(new UIDialog.OnListener() {
                            @Override
                            public void onConfirm(BaseDialog dialog) {
                                viewModel.deleteItem(mDataList.get(position));
                            }
                        })
                        .show();
            }
        });
        ElectronicFileAdapter adapter = new ElectronicFileAdapter(mContext);
        holder.getBinding().rvImage.setLayoutManager(new GridLayoutManager(mContext,3));
        holder.getBinding().rvImage.setAdapter(adapter);
        adapter.setData(Utils.splitString2List(mDataList.get(position).getUrl(),","));
    }
    public void setCheckable(boolean b) {
        isCheckable = b;
        notifyDataSetChanged();
    }
    public static class ViewHolder extends BaseRVAdapter.BaseViewHolder<ItemExaminationInfoBinding> {
        public ViewHolder(ItemExaminationInfoBinding binding) {
            super(binding);
        }
    }
}
app/src/main/java/com/application/zhangshi_app_android/bean/AnnualHealthStatusBean.java
@@ -9,7 +9,7 @@
 */
public class AnnualHealthStatusBean implements Serializable {
    //序号
    private int id;
    private int id = -1;
    //体检时间
    private String checkTime;
    //类别
app/src/main/java/com/application/zhangshi_app_android/bean/ExaminationInfoBean.java
New file
@@ -0,0 +1,61 @@
package com.application.zhangshi_app_android.bean;
import java.io.Serializable;
/**
 * @author Ljj
 * @date 2023.10.23. 22:12
 * @desc 体检信息
 */
public class ExaminationInfoBean implements Serializable {
    //id
    private int id;
    //uid
    private int uid;
    //体检日期
    private String happenTime;
    //年度报告
    private String report;
    //电子文件
    private String url;
    public String getHappenTime() {
        return happenTime;
    }
    public void setHappenTime(String happenTime) {
        this.happenTime = happenTime;
    }
    public String getReport() {
        return report;
    }
    public void setReport(String report) {
        this.report = report;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getUid() {
        return uid;
    }
    public void setUid(int uid) {
        this.uid = uid;
    }
}
app/src/main/java/com/application/zhangshi_app_android/bean/ExaminationInfoRequestBean.java
New file
@@ -0,0 +1,47 @@
package com.application.zhangshi_app_android.bean;
import java.util.Map;
/**
 * @author Ljj
 * @date 2023.10.23. 22:24
 * @desc 体检信息请求bean
 */
public class ExaminationInfoRequestBean extends PageRequestBean{
    private String report;
    private String happenStartTime;
    private String happenEndTime;
    public String getReport() {
        return report;
    }
    public void setReport(String report) {
        this.report = report;
    }
    public String getHappenStartTime() {
        return happenStartTime;
    }
    public void setHappenStartTime(String happenStartTime) {
        this.happenStartTime = happenStartTime;
    }
    public String getHappenEndTime() {
        return happenEndTime;
    }
    public void setHappenEndTime(String happenEndTime) {
        this.happenEndTime = happenEndTime;
    }
    @Override
    public Map<String, Object> toMap() {
        Map<String, Object> map = super.toMap();
        map.put("report",report == null ? "" : report);
        map.put("happenStartTime",happenStartTime == null ? "" : happenStartTime);
        map.put("happenEndTime",happenEndTime == null ? "" : happenEndTime);
        return map;
    }
}
app/src/main/java/com/application/zhangshi_app_android/data/DataRepository.java
@@ -10,6 +10,7 @@
import com.application.zhangshi_app_android.bean.CertificateOfHonorBean;
import com.application.zhangshi_app_android.bean.CleanStorageBean;
import com.application.zhangshi_app_android.bean.ContactsDetailBean;
import com.application.zhangshi_app_android.bean.ExaminationInfoBean;
import com.application.zhangshi_app_android.bean.FamilyAssetsBean;
import com.application.zhangshi_app_android.bean.FamilyMemorabiliaBean;
import com.application.zhangshi_app_android.bean.GrowthExperienceAbroadConditionBean;
@@ -656,6 +657,34 @@
        return mHttpDataSource.getUpdateVersion();
    }
    /**
     *  获取历年体检报告
     */
    public Observable<ResultData<PageResponseBean<ExaminationInfoBean>>> getExaminationInfo(Map<String, Object> toMap) {
        return mHttpDataSource.getExaminationInfo(toMap);
    }
    /**
     *  删除历年体检报告
     */
    public Observable<ResultData<String>> deleteExaminationInfo(String ids) {
        return mHttpDataSource.deleteExaminationInfo(ids);
    }
    /**
     *  修改历年体检报告
     */
    public Observable<ResultData<String>> updateExaminationInfo(ExaminationInfoBean examinationInfoBean) {
        return mHttpDataSource.updateExaminationInfo(examinationInfoBean);
    }
    /**
     *  添加历年体检报告
     */
    public Observable<ResultData<String>> addExaminationInfo(ExaminationInfoBean examinationInfoBean) {
        return mHttpDataSource.addExaminationInfo(examinationInfoBean);
    }
    /**
     * @see LocalDataSourceImpl
app/src/main/java/com/application/zhangshi_app_android/data/source/HttpDataSource.java
@@ -7,6 +7,7 @@
import com.application.zhangshi_app_android.bean.CertificateOfHonorBean;
import com.application.zhangshi_app_android.bean.CleanStorageBean;
import com.application.zhangshi_app_android.bean.ContactsDetailBean;
import com.application.zhangshi_app_android.bean.ExaminationInfoBean;
import com.application.zhangshi_app_android.bean.HealthCareBaseInfoBean;
import com.application.zhangshi_app_android.bean.HealthCareExistingProblemsBean;
import com.application.zhangshi_app_android.bean.HealthCareLifeHabitsBean;
@@ -440,6 +441,26 @@
    Observable<ResultData<UpdateVersionBean>> getUpdateVersion();
    /**
     *  获取历年体检报告
     */
    Observable<ResultData<PageResponseBean<ExaminationInfoBean>>> getExaminationInfo(Map<String, Object> toMap);
    /**
     *  删除历年体检报告
     */
    Observable<ResultData<String>> deleteExaminationInfo(String ids);
    /**
     *  修改历年体检报告
     */
    Observable<ResultData<String>> updateExaminationInfo(ExaminationInfoBean examinationInfoBean);
    /**
     *  添加历年体检报告
     */
    Observable<ResultData<String>> addExaminationInfo(ExaminationInfoBean examinationInfoBean);
}
app/src/main/java/com/application/zhangshi_app_android/data/source/http/ApiService.java
@@ -7,6 +7,7 @@
import com.application.zhangshi_app_android.bean.CertificateOfHonorBean;
import com.application.zhangshi_app_android.bean.CleanStorageBean;
import com.application.zhangshi_app_android.bean.ContactsDetailBean;
import com.application.zhangshi_app_android.bean.ExaminationInfoBean;
import com.application.zhangshi_app_android.bean.HealthCareBaseInfoBean;
import com.application.zhangshi_app_android.bean.HealthCareExistingProblemsBean;
import com.application.zhangshi_app_android.bean.HealthCareLifeHabitsBean;
@@ -548,4 +549,28 @@
    @GET("/version")
    Observable<ResultData<UpdateVersionBean>> getUpdateVersion();
    /**
     * 获取历年体检报告
     */
    @GET("/physcial/all")
    Observable<ResultData<PageResponseBean<ExaminationInfoBean>>> getExaminationInfo(@QueryMap Map<String, Object> toMap);
    /**
     * 删除历年体检报告
     */
    @DELETE("/physcial/{ids}")
    Observable<ResultData<String>> deleteExaminationInfo(@Path("ids") String ids);
    /**
     * 修改历年体检报告
     */
    @PUT("/physcial")
    Observable<ResultData<String>> updateExaminationInfo(@Body ExaminationInfoBean examinationInfoBean);
    /**
     * 添加历年体检报告
     */
    @POST("/physcial")
    Observable<ResultData<String>> addExaminationInfo(@Body ExaminationInfoBean examinationInfoBean);
}
app/src/main/java/com/application/zhangshi_app_android/data/source/http/HttpDataSourceImpl.java
@@ -8,6 +8,7 @@
import com.application.zhangshi_app_android.bean.CertificateOfHonorBean;
import com.application.zhangshi_app_android.bean.CleanStorageBean;
import com.application.zhangshi_app_android.bean.ContactsDetailBean;
import com.application.zhangshi_app_android.bean.ExaminationInfoBean;
import com.application.zhangshi_app_android.bean.HealthCareBaseInfoBean;
import com.application.zhangshi_app_android.bean.HealthCareExistingProblemsBean;
import com.application.zhangshi_app_android.bean.HealthCareLifeHabitsBean;
@@ -62,7 +63,7 @@
    private volatile static HttpDataSourceImpl INSTANCE = null;
    private HttpDataSourceImpl() {
        this.apiService = RetrofitManager.getInstance().getRetrofit(BaseConfig.BASE_URL).create(ApiService.class);
        this.apiService = RetrofitManager.getInstance().getRetrofit(BaseConfig.BASE_URL_DOMAIN).create(ApiService.class);
    }
    public static HttpDataSourceImpl getInstance() {
@@ -710,4 +711,36 @@
    public Observable<ResultData<UpdateVersionBean>> getUpdateVersion() {
        return apiService.getUpdateVersion();
    }
    /**
     *  获取历年体检报告
     */
    @Override
    public Observable<ResultData<PageResponseBean<ExaminationInfoBean>>> getExaminationInfo(Map<String, Object> toMap) {
        return apiService.getExaminationInfo(toMap);
    }
    /**
     *  删除历年体检报告
     */
    @Override
    public Observable<ResultData<String>> deleteExaminationInfo(String ids) {
        return apiService.deleteExaminationInfo(ids);
    }
    /**
     *  修改历年体检报告
     */
    @Override
    public Observable<ResultData<String>> updateExaminationInfo(ExaminationInfoBean examinationInfoBean) {
        return apiService.updateExaminationInfo(examinationInfoBean);
    }
    /**
     *  新增历年体检报告
     */
    @Override
    public Observable<ResultData<String>> addExaminationInfo(ExaminationInfoBean examinationInfoBean) {
        return apiService.addExaminationInfo(examinationInfoBean);
    }
}
app/src/main/java/com/application/zhangshi_app_android/ui/BrowserActivity.java
New file
@@ -0,0 +1,184 @@
package com.application.zhangshi_app_android.ui;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.text.TextUtils;
import android.util.Base64;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.annotation.NonNull;
import com.android.app_base.base.dialog.BaseDialog;
import com.android.app_base.base.dialog.WaitDialog;
import com.android.app_base.base.view.BaseActivity;
import com.application.zhangshi_app_android.R;
import com.application.zhangshi_app_android.databinding.ActivityBrowserBinding;
import com.hjq.bar.TitleBar;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnRefreshListener;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
 * @author Ljj
 * @date 2023.10.15. 22:36
 * @desc 浏览器界面
 */
public class BrowserActivity extends BaseActivity<ActivityBrowserBinding,SimpleViewModel> {
    private static final String INTENT_URL = "url";
    private String url;
    private BaseDialog mWaitDialog;
    public static void start(Context context, String url) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        Intent intent = new Intent(context, BrowserActivity.class);
        intent.putExtra(INTENT_URL, url);
        if (!(context instanceof Activity)) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        context.startActivity(intent);
    }
    @Override
    public int getLayoutId() {
        return R.layout.activity_browser;
    }
    @Override
    public int getVariableId() {
        return 0;
    }
    @Override
    public void initParam() {
        url = getIntent().getStringExtra(INTENT_URL);
    }
    @Override
    public void initView() {
        binding.slBrowserRefresh.setEnableRefresh(true);
        binding.slBrowserRefresh.setEnableLoadMore(false);
        binding.slBrowserRefresh.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
                binding.wvBrowserView.reload();
            }
        });
        WebSettings webSettings = binding.wvBrowserView.getSettings();
        webSettings.setJavaScriptEnabled(true); // 启用JavaScript
        webSettings.setBuiltInZoomControls(true); // 启用内置的缩放控件
        webSettings.setDisplayZoomControls(false); // 隐藏缩放按钮
        webSettings.setSupportZoom(true); // 启用缩放
        webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小
        webSettings.setUseWideViewPort(true); // 启用支持视窗
        binding.wvBrowserView.setWebViewClient(new WebViewClient(){
            /**
             * 开始加载网页
             */
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                binding.pbBrowserProgress.setVisibility(View.VISIBLE);
            }
            /**
             * 完成加载网页
             */
            @Override
            public void onPageFinished(WebView view, String url) {
                binding.pbBrowserProgress.setVisibility(View.GONE);
                binding.slBrowserRefresh.finishRefresh();
                dialogDismiss();
            }
        });
        binding.wvBrowserView.setWebChromeClient(new WebChromeClient(){
            /**
             * 收到网页标题
             */
            @Override
            public void onReceivedTitle(WebView view, String title) {
                if (title == null) {
                    return;
                }
                binding.tbBrowserTitle.setTitle(title);
            }
            @Override
            public void onReceivedIcon(WebView view, Bitmap icon) {
                if (icon == null) {
                    return;
                }
//                setRightIcon(new BitmapDrawable(getResources(), icon));
            }
            /**
             * 收到加载进度变化
             */
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                binding.pbBrowserProgress.setProgress(newProgress);
            }
        });
    }
    @Override
    public void initData() {
        dialogLoading();
        binding.wvBrowserView.loadUrl(url);
    }
    @Override
    public void initLiveDataObserve() {
    }
    @Override
    public void onLeftClick(TitleBar titleBar) {
        finish();
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && binding.wvBrowserView.canGoBack()) {
            // 后退网页并且拦截该事件
            binding.wvBrowserView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
    @Override
    protected void dialogLoading() {
        if (mWaitDialog == null) {
            mWaitDialog = new WaitDialog.Builder(this)
                    .create();
            mWaitDialog.setCancelable(true);
        }
        if (!mWaitDialog.isShowing()) {
            mWaitDialog.show();
        }
    }
    @Override
    protected void dialogDismiss() {
        if (mWaitDialog != null && mWaitDialog.isShowing()) {
            mWaitDialog.dismiss();
            mWaitDialog = null;
        }
    }
}
app/src/main/java/com/application/zhangshi_app_android/ui/DLBaseActivity.java
@@ -15,6 +15,7 @@
import androidx.databinding.ViewDataBinding;
import androidx.drawerlayout.widget.DrawerLayout;
import com.android.app_base.base.BaseConfig;
import com.android.app_base.base.view.BaseActivity;
import com.android.app_base.base.viewmodel.BaseViewModel;
import com.android.app_base.manager.AppManager;
@@ -24,13 +25,13 @@
import com.android.app_base.utils.rxbus.MessageEvent;
import com.android.app_base.utils.rxbus.RxBus;
import com.application.zhangshi_app_android.R;
import com.application.zhangshi_app_android.ui.function.AnnualHealthStatusActivity;
import com.application.zhangshi_app_android.ui.function.CertificateOfHonorActivity;
import com.application.zhangshi_app_android.ui.function.CleanStorageActivity;
import com.application.zhangshi_app_android.ui.function.ContactsActivity;
import com.application.zhangshi_app_android.ui.function.FamilyAssetsActivity;
import com.application.zhangshi_app_android.ui.function.FamilyMemorabiliaActivity;
import com.application.zhangshi_app_android.ui.function.GrowthExperienceActivity;
import com.application.zhangshi_app_android.ui.function.HealthCareActivity;
import com.application.zhangshi_app_android.ui.function.HomeDevicesActivity;
import com.application.zhangshi_app_android.ui.function.HonorCollectionActivity;
import com.application.zhangshi_app_android.ui.function.HundredWishActivity;
@@ -38,7 +39,6 @@
import com.application.zhangshi_app_android.ui.function.LittleDoctorActivity;
import com.application.zhangshi_app_android.ui.function.MarriageActivity;
import com.application.zhangshi_app_android.ui.function.PetActivity;
import com.application.zhangshi_app_android.ui.function.PetDetailActivity;
import com.application.zhangshi_app_android.ui.function.PrivacyActivity;
import com.application.zhangshi_app_android.ui.function.PropertyActivity;
import com.application.zhangshi_app_android.ui.function.TourismActivity;
@@ -121,7 +121,7 @@
            classMap.put(MarriageActivity.class,(LinearLayout) findViewById(R.id.dl_marriage));
            classMap.put(PropertyActivity.class,(LinearLayout) findViewById(R.id.dl_property));
            classMap.put(HundredWishActivity.class,(LinearLayout) findViewById(R.id.dl_hundred_wish));
            classMap.put(HealthCareActivity.class,(LinearLayout) findViewById(R.id.dl_health_care));
            classMap.put(AnnualHealthStatusActivity.class,(LinearLayout) findViewById(R.id.dl_health_care));
            classMap.put(CertificateOfHonorActivity.class,(LinearLayout) findViewById(R.id.dl_certificate_of_honor));
            classMap.put(PrivacyActivity.class,(LinearLayout) findViewById(R.id.dl_privacy));
            classMap.put(TourismActivity.class,(LinearLayout) findViewById(R.id.dl_tourism));
@@ -135,8 +135,11 @@
                            if (set.getKey() == HomeFragment.class) {
                                MainActivity.start(this, HomeFragment.class);
                            }else{
                                if(this.getClass() != set.getKey()){
                                AppManager.getAppManager().startActivity(set.getKey());
                            }
                            }
                            mDrawerLayout.close();
                        }
                    });
                } else {
@@ -160,6 +163,11 @@
    public void setNameAndAvatar(String name,String avatar){
        if (mDrawerLayout != null){
            if (avatar.contains("profile/upload")) {//如果是上传到服务器的图片
                //只取profile/upload以后的部分
                avatar = avatar.substring(avatar.indexOf("profile/upload"));
                avatar = BaseConfig.BASE_URL_DOMAIN + "/" + avatar;
            }
            GlideUtil.loadImage(avatar, findViewById(R.id.dl_home_user_avatar));
            TextView userNameTv = findViewById(R.id.dl_home_user_name);
            userNameTv.setText(name);
app/src/main/java/com/application/zhangshi_app_android/ui/DLBaseFragment.java
@@ -17,6 +17,7 @@
import androidx.databinding.ViewDataBinding;
import androidx.drawerlayout.widget.DrawerLayout;
import com.android.app_base.base.BaseConfig;
import com.android.app_base.base.view.BaseFragment;
import com.android.app_base.base.viewmodel.BaseViewModel;
import com.android.app_base.manager.AppManager;
@@ -25,13 +26,13 @@
import com.android.app_base.utils.rxbus.MessageEvent;
import com.android.app_base.utils.rxbus.RxBus;
import com.application.zhangshi_app_android.R;
import com.application.zhangshi_app_android.ui.function.AnnualHealthStatusActivity;
import com.application.zhangshi_app_android.ui.function.CertificateOfHonorActivity;
import com.application.zhangshi_app_android.ui.function.CleanStorageActivity;
import com.application.zhangshi_app_android.ui.function.ContactsActivity;
import com.application.zhangshi_app_android.ui.function.FamilyAssetsActivity;
import com.application.zhangshi_app_android.ui.function.FamilyMemorabiliaActivity;
import com.application.zhangshi_app_android.ui.function.GrowthExperienceActivity;
import com.application.zhangshi_app_android.ui.function.HealthCareActivity;
import com.application.zhangshi_app_android.ui.function.HomeDevicesActivity;
import com.application.zhangshi_app_android.ui.function.HonorCollectionActivity;
import com.application.zhangshi_app_android.ui.function.HundredWishActivity;
@@ -43,6 +44,7 @@
import com.application.zhangshi_app_android.ui.function.PropertyActivity;
import com.application.zhangshi_app_android.ui.function.TourismActivity;
import com.application.zhangshi_app_android.ui.home.HomeFragment;
import com.application.zhangshi_app_android.ui.main.MainActivity;
import com.hjq.bar.TitleBar;
import java.util.HashMap;
@@ -128,7 +130,7 @@
            classMap.put(MarriageActivity.class,(LinearLayout) findViewById(R.id.dl_marriage));
            classMap.put(PropertyActivity.class,(LinearLayout) findViewById(R.id.dl_property));
            classMap.put(HundredWishActivity.class,(LinearLayout) findViewById(R.id.dl_hundred_wish));
            classMap.put(HealthCareActivity.class,(LinearLayout) findViewById(R.id.dl_health_care));
            classMap.put(AnnualHealthStatusActivity.class,(LinearLayout) findViewById(R.id.dl_health_care));
            classMap.put(CertificateOfHonorActivity.class,(LinearLayout) findViewById(R.id.dl_certificate_of_honor));
            classMap.put(PrivacyActivity.class,(LinearLayout) findViewById(R.id.dl_privacy));
            classMap.put(TourismActivity.class,(LinearLayout) findViewById(R.id.dl_tourism));
@@ -139,7 +141,12 @@
                if (linearLayout != null) {
                    linearLayout.setOnClickListener(v -> {
                        if (set.getKey() != null){
                            if (set.getKey() == HomeFragment.class) {
                                MainActivity.start(getContext(), HomeFragment.class);
                            }else{
                            AppManager.getAppManager().startActivity(set.getKey());
                            }
                            mDrawerLayout.close();
                        }
                    });
                } else {
@@ -171,6 +178,11 @@
    public void setNameAndAvatar(String name,String avatar){
        if (mDrawerLayout != null){
            if (avatar.contains("profile/upload")) {//如果是上传到服务器的图片
                //只取profile/upload以后的部分
                avatar = avatar.substring(avatar.indexOf("profile/upload"));
                avatar = BaseConfig.BASE_URL_DOMAIN + "/" + avatar;
            }
            GlideUtil.loadImage(avatar, findViewById(R.id.dl_home_user_avatar));
            TextView userNameTv = findViewById(R.id.dl_home_user_name);
            userNameTv.setText(name);
app/src/main/java/com/application/zhangshi_app_android/ui/PlayerActivity.java
File was renamed from app/src/main/java/com/application/zhangshi_app_android/ui/PlayActivity.java
@@ -2,13 +2,11 @@
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Build;
import android.os.Handler;
import android.transition.Transition;
import android.transition.TransitionListenerAdapter;
import android.view.View;
import android.widget.ImageView;
@@ -17,6 +15,7 @@
import androidx.core.util.Pair;
import androidx.core.view.ViewCompat;
import com.android.app_base.base.BaseConfig;
import com.android.app_base.base.view.BaseActivity;
import com.android.app_base.utils.GlideUtil;
import com.application.zhangshi_app_android.R;
@@ -24,15 +23,12 @@
import com.shuyu.gsyvideoplayer.GSYVideoManager;
import com.shuyu.gsyvideoplayer.utils.OrientationUtils;
import java.util.ArrayList;
import java.util.List;
/**
 * @author Ljj
 * @date 2023.09.04. 15:59
 * @desc
 * @desc 视频播放 Activity
 */
public class PlayActivity extends BaseActivity<ActivityPlayBinding,SimpleViewModel> {
public class PlayerActivity extends BaseActivity<ActivityPlayBinding,SimpleViewModel> {
    public final static String IMG_TRANSITION = "IMG_TRANSITION";
    public final static String TRANSITION = "TRANSITION";
    public final static String VIDEO_URL = "VIDEO_URL";
@@ -228,11 +224,11 @@
     * @param isTransition 是否有过渡动画
     */
    public static void start(Activity activity, String url, View view, boolean isTransition){
        Intent intent = new Intent(activity, PlayActivity.class);
        intent.putExtra(PlayActivity.TRANSITION, isTransition);
        intent.putExtra(PlayActivity.VIDEO_URL, url);
        Intent intent = new Intent(activity, PlayerActivity.class);
        intent.putExtra(PlayerActivity.TRANSITION, isTransition);
        intent.putExtra(PlayerActivity.VIDEO_URL, url);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            Pair pair = new Pair<>(view, PlayActivity.IMG_TRANSITION);
            Pair pair = new Pair<>(view, PlayerActivity.IMG_TRANSITION);
            ActivityOptionsCompat activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(
                    activity, pair);
            ActivityCompat.startActivity(activity, intent, activityOptions.toBundle());
@@ -241,4 +237,20 @@
            activity.overridePendingTransition(androidx.appcompat.R.anim.abc_fade_in, androidx.appcompat.R.anim.abc_fade_out);
        }
    }
    /**
     * 启动播放界面(拼接完整的url)
     * @param activity
     * @param url
     * @param view
     * @param isTransition
     */
    public static void startWrapUrl(Activity activity, String url, View view, boolean isTransition){
        if (url.contains("profile/upload")) {//如果是上传到服务器的图片
            //只取profile/upload以后的部分
            url = url.substring(url.indexOf("profile/upload"));
            url = BaseConfig.BASE_URL_DOMAIN + "/" + url;
        }
        start(activity,url,view,isTransition);
    }
}
app/src/main/java/com/application/zhangshi_app_android/ui/dialog/UpdateDialog.java
@@ -41,7 +41,9 @@
import java.util.Timer;
import java.util.TimerTask;
/**
 *  版本更新弹窗
 */
public final class UpdateDialog {
    public static final class Builder
app/src/main/java/com/application/zhangshi_app_android/ui/dialog/VersionUpdateDialog.java
File was deleted
app/src/main/java/com/application/zhangshi_app_android/ui/function/AnnualHealthStatusActivity.java
@@ -69,12 +69,14 @@
        binding.recyclerView.addItemDecoration(itemDecoration);
        binding.recyclerView.setAdapter(adapter);
        //右上角操作弹窗
        mOperatePopupWindow = initPopUpWindow(View.inflate(this,R.layout.pop_operate,null));
        mOperatePopupWindow = initPopUpWindow(View.inflate(this, R.layout.pop_operate_exam_info, null));
        setOnClickListener(
                mOperatePopupWindow.getContentView().findViewById(R.id.tv_add),
                mOperatePopupWindow.getContentView().findViewById(R.id.tv_select),
                mOperatePopupWindow.getContentView().findViewById(R.id.tv_from_new_to_old),
                mOperatePopupWindow.getContentView().findViewById(R.id.tv_from_old_to_new)
                mOperatePopupWindow.getContentView().findViewById(R.id.tv_from_old_to_new),
                mOperatePopupWindow.getContentView().findViewById(R.id.tv_exam_info),
                mOperatePopupWindow.getContentView().findViewById(R.id.tv_health_care)
        );
        //点击放大镜按钮显示出搜索框
        binding.ivSearchDefault.setOnClickListener(v -> {
@@ -235,7 +237,7 @@
            if (integer == 0){
                binding.ivOperate.setBackgroundResource(R.drawable.ic_operate);
                binding.ivOperate.setOnClickListener(v -> {
                    mOperatePopupWindow.showAsDropDown(binding.ivOperate,-ScreenSizeUtils.dip2px(this,85) +binding.ivOperate.getWidth(),0);
                    mOperatePopupWindow.showAsDropDown(binding.ivOperate,-ScreenSizeUtils.dip2px(this,118) +binding.ivOperate.getWidth(),0);
                });
                adapter.setCheckable(false);
            }else if (integer == 1){
@@ -311,6 +313,12 @@
        } else if (id == R.id.tv_from_old_to_new) {
            viewModel.changeOrder(false);
            mOperatePopupWindow.dismiss();
        }else if (id == R.id.tv_health_care){
            AppManager.getAppManager().startActivity(HealthCareActivity.class);
            mOperatePopupWindow.dismiss();
        }else if (id == R.id.tv_exam_info){
            AppManager.getAppManager().startActivity(ExaminationInfoActivity.class);
            mOperatePopupWindow.dismiss();
        }
    }
@@ -336,8 +344,5 @@
        return super.dispatchTouchEvent(event);
    }
    @Override
    public void onLeftClick(TitleBar titleBar) {
        finish();
    }
}
app/src/main/java/com/application/zhangshi_app_android/ui/function/AnnualHealthStatusActivityViewModel.java
@@ -96,10 +96,6 @@
     * 加载更多
     */
    public void getMoreAnnualHealthStatus() {
        if (true){
            changeStateView(StateViewEnum.DATA_NULL);
            return;
        }
        if (getRequestBeanLiveData().getValue() == null){
            getRequestBeanLiveData().setValue(new AnnualHealthStatusRequestBean());
        }
app/src/main/java/com/application/zhangshi_app_android/ui/function/AnnualHealthStatusDetailActivity.java
@@ -85,9 +85,6 @@
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
        binding.rvImage.setLayoutManager(gridLayoutManager);
        binding.rvImage.setNestedScrollingEnabled(false);
        View footerView = View.inflate(this,R.layout.item_image_footer,null);
        binding.rvImage.addFooterView(footerView);
        binding.rvImage.requestLayout();
        adapter.setItemAndAddClickListener(new ElectronicFileAddAdapter.OnItemAndAddClickListener() {
            @Override
            public void onItemClick(View v, int position) {
app/src/main/java/com/application/zhangshi_app_android/ui/function/CertificateOfHonorActivityViewModel.java
@@ -177,7 +177,6 @@
        if (list == null || list.isEmpty()){
            return;
        }
        System.out.println(dataListLiveData.getValue().size());
        if (type == 0) {
            // 从新到旧,null排最后
            list.sort((o1, o2) -> {
app/src/main/java/com/application/zhangshi_app_android/ui/function/ExaminationInfoActivity.java
New file
@@ -0,0 +1,348 @@
package com.application.zhangshi_app_android.ui.function;
import android.content.Intent;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.MotionEvent;
import android.view.View;
import android.widget.PopupWindow;
import com.android.app_base.base.BaseConfig;
import com.android.app_base.base.dialog.BaseDialog;
import com.android.app_base.base.dialog.UIDialog;
import com.android.app_base.manager.AppManager;
import com.android.app_base.utils.ScreenSizeUtils;
import com.android.app_base.utils.Utils;
import com.android.app_base.utils.rxbus.RxBus;
import com.android.app_base.widget.LinearItemDecoration;
import com.application.zhangshi_app_android.BR;
import com.application.zhangshi_app_android.R;
import com.application.zhangshi_app_android.adapter.ExaminationInfoRvAdapter;
import com.application.zhangshi_app_android.bean.ExaminationInfoBean;
import com.application.zhangshi_app_android.databinding.ActivityExaminationInfoBinding;
import com.application.zhangshi_app_android.ui.DLBaseActivity;
import com.github.gzuliyujiang.wheelpicker.DatePicker;
import com.github.gzuliyujiang.wheelpicker.contract.OnDatePickedListener;
import com.hjq.bar.TitleBar;
/**
 * @author Ljj
 * @date 2023.10.23. 22:02
 * @desc 历年体检信息
 */
public class ExaminationInfoActivity extends DLBaseActivity<ActivityExaminationInfoBinding,ExaminationInfoActivityViewModel > {
    private ExaminationInfoRvAdapter adapter;
    private boolean isSearchLayoutVisible;
    private PopupWindow mOperatePopupWindow;
    @Override
    public int getLayoutId() {
        return R.layout.activity_examination_info;
    }
    @Override
    public int getVariableId() {
        return BR.viewModel;
    }
    @Override
    public void initParam() {
    }
    @Override
    public void initView() {
        //下拉刷新布局
        binding.refreshLayout.setEnableRefresh(false);
        binding.refreshLayout.setEnableLoadMore(true);
        binding.refreshLayout.setEnableOverScrollDrag(true);
        binding.refreshLayout.setOnLoadMoreListener(refreshLayout -> {
            viewModel.getMoreExaminationInfo();
        });
        //recyclerView适配器
        adapter = new ExaminationInfoRvAdapter(this, viewModel);
        LinearItemDecoration itemDecoration = new LinearItemDecoration();
        itemDecoration.setBottomSpace((int) getResources().getDimension(com.android.app_base.R.dimen.dp_12));
        itemDecoration.setHorizontalSpace((int) getResources().getDimension(com.android.app_base.R.dimen.dp_20));
        itemDecoration.setFirstTop((int) getResources().getDimension(com.android.app_base.R.dimen.dp_20));
        binding.recyclerView.addItemDecoration(itemDecoration);
        binding.recyclerView.setAdapter(adapter);
        //右上角操作弹窗
        mOperatePopupWindow = initPopUpWindow(View.inflate(this,R.layout.pop_operate,null));
        mOperatePopupWindow.getContentView().findViewById(R.id.layout_own_top).setVisibility(View.GONE);
        setOnClickListener(
                mOperatePopupWindow.getContentView().findViewById(R.id.tv_add),
                mOperatePopupWindow.getContentView().findViewById(R.id.tv_select),
                mOperatePopupWindow.getContentView().findViewById(R.id.tv_from_new_to_old),
                mOperatePopupWindow.getContentView().findViewById(R.id.tv_from_old_to_new)
        );
        //点击放大镜按钮显示出搜索框
        binding.ivSearchDefault.setOnClickListener(v -> {
            binding.layoutSearch.setVisibility(View.VISIBLE);
            binding.layoutDefault.setVisibility(View.GONE);
        });
        //点击搜索框菜单下拉出 搜索参数
        binding.ivSearchType.setOnClickListener(v -> {
            if (!isSearchLayoutVisible) {
                binding.layoutSearchParameter.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
                int targetHeight = binding.layoutSearchParameter.getMeasuredHeight();
                Utils.dropExpand(binding.containerSearchParameter, 0, targetHeight);
                isSearchLayoutVisible = true;
            }
        });
        //搜索参数layout添加空点击事件,防止点击它内部view时它后面的recycler还能响应点击事件
        binding.layoutSearchParameter.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
        //点击搜索按钮进行搜索
        binding.ivSearch.setOnClickListener(v -> {
            viewModel.getExaminationInfo();
            binding.layoutSearch.setVisibility(View.GONE);
            binding.layoutDefault.setVisibility(View.VISIBLE);
            binding.tvTitle.setText("搜索结果");
            hideSoftKeyboard();
        });
        //点击添加按钮跳转到创建页面
        binding.fabAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AppManager.getAppManager().startActivity(new Intent(getSelfActivity(), ExaminationInfoDetailActivity.class).putExtra(BaseConfig.EXTRA_TYPE, 1));
            }
        });
        binding.etStartTime.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (!TextUtils.isEmpty(s)) {
                    binding.ivTimeClear.setVisibility(View.VISIBLE);
                } else {
                    if (TextUtils.isEmpty(binding.etEndTime.getText().toString())) {
                        binding.ivTimeClear.setVisibility(View.INVISIBLE);
                    }
                }
            }
            @Override
            public void afterTextChanged(Editable s) {
            }
        });
        binding.etEndTime.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (!TextUtils.isEmpty(s)) {
                    binding.ivTimeClear.setVisibility(View.VISIBLE);
                } else {
                    if (TextUtils.isEmpty(binding.etStartTime.getText().toString())) {
                        binding.ivTimeClear.setVisibility(View.INVISIBLE);
                    }
                }
            }
            @Override
            public void afterTextChanged(Editable s) {
            }
        });
        binding.etStartTime.setOnClickListener(v -> {
            hideSoftKeyboard();
            DatePicker datePicker = getDatePicker();
            datePicker.setTitle("请选择开始时间");
            datePicker.setOnDatePickedListener(new OnDatePickedListener() {
                @Override
                public void onDatePicked(int year, int month, int day) {
                    //以yyyy-MM-dd的格式显示,月日小于10时前面补0
                    binding.etStartTime.setText(String.format("%d-%02d-%02d", year, month, day));
                    if (binding.etEndTime.getText().toString().isEmpty()) {
                        binding.etEndTime.setText(String.format("%d-%02d-%02d", year, month, day));
                    } else {
                        //比较开始时间和结束时间的大小
                        String startTime = binding.etStartTime.getText().toString();
                        String endTime = binding.etEndTime.getText().toString();
                        if (Utils.compareDate(startTime, endTime) > 0) {
                            //交换
                            binding.etStartTime.setText(endTime);
                            binding.etEndTime.setText(startTime);
                        }
                    }
                }
            });
            datePicker.show();
        });
        binding.etEndTime.setOnClickListener(v -> {
            hideSoftKeyboard();
            DatePicker datePicker = getDatePicker();
            datePicker.setTitle("请选择结束时间");
            datePicker.setOnDatePickedListener(new OnDatePickedListener() {
                @Override
                public void onDatePicked(int year, int month, int day) {
                    binding.etEndTime.setText(String.format("%d-%02d-%02d", year, month, day));
                    if (binding.etStartTime.getText().toString().isEmpty()) {
                        binding.etStartTime.setText(String.format("%d-%02d-%02d", year, month, day));
                    } else {
                        //比较开始时间和结束时间的大小
                        String startTime = binding.etStartTime.getText().toString();
                        String endTime = binding.etEndTime.getText().toString();
                        if (Utils.compareDate(startTime, endTime) > 0) {
                            //交换
                            binding.etStartTime.setText(endTime);
                            binding.etEndTime.setText(startTime);
                        }
                    }
                }
            });
            datePicker.show();
        });
        binding.ivTimeClear.setOnClickListener(v -> {
            binding.etStartTime.setText("");
            binding.etEndTime.setText("");
        });
    }
    @Override
    public void initData() {
        viewModel.getExaminationInfo();
    }
    @Override
    public void initLiveDataObserve() {
        viewModel.getDataListLiveData().observe(this, dataList -> {
            adapter.setData(dataList);
        });
        viewModel.getCheckListLiveData().observe(this, checkList -> {
            if (0 == viewModel.getOperateTypeLiveData().getValue()) {
                return;
            }
            if (checkList.isEmpty()) {
                viewModel.getOperateTypeLiveData().setValue(1);
            } else {
                viewModel.getOperateTypeLiveData().setValue(2);
            }
        });
        viewModel.getMoreListLiveData().observe(this, moreList -> {
            adapter.addData(moreList);
        });
        viewModel.getOperateTypeLiveData().observe(this, integer -> {
            if (integer == 0) {
                binding.ivOperate.setBackgroundResource(R.drawable.ic_operate);
                binding.ivOperate.setOnClickListener(v -> {
                    mOperatePopupWindow.showAsDropDown(binding.ivOperate, -ScreenSizeUtils.dip2px(this, 85) + binding.ivOperate.getWidth(), 0);
                });
                adapter.setCheckable(false);
            } else if (integer == 1) {
                binding.ivOperate.setBackgroundResource(R.drawable.ic_operate_finish);
                binding.ivOperate.setOnClickListener(v -> {
                    viewModel.getOperateTypeLiveData().postValue(0);
                });
                adapter.setCheckable(true);
            } else if (integer == 2) {
                binding.ivOperate.setBackgroundResource(R.drawable.ic_delete_white);
                binding.ivOperate.setOnClickListener(v -> {
                    new UIDialog.Builder(this)
                            .setTitle("您确定要删除选中的项目吗")
                            .setContent("项目删除后将无法恢复")
                            .setConfirm("确定")
                            .setCancel("取消")
                            .setListener(new UIDialog.OnListener() {
                                @Override
                                public void onConfirm(BaseDialog dialog) {
                                    viewModel.deleteCheckList();
                                }
                            })
                            .show();
                });
            }
        });
        viewModel.getFinishDeleteListLiveData().observe(this, beans -> {
            for (ExaminationInfoBean bean : beans) {
                adapter.removeItem(bean);
            }
        });
        //观察数据的变化,有变化包括添加、修改、删除都会发送消息,接收到消息后重新获取数据进行刷新
        RxBus.getInstance().toObservable(this, ExaminationInfoBean.class)
                .subscribe(bean -> {
                    viewModel.getExaminationInfo();
                });
    }
    @Override
    protected void dataNull() {
        super.dataNull();
        binding.layoutDataNull.setVisibility(View.VISIBLE);
        binding.refreshLayout.setVisibility(View.GONE);
    }
    @Override
    protected void dataFinish() {
        super.dataFinish();
        binding.refreshLayout.finishLoadMore();
    }
    @Override
    protected void hide() {
        super.hide();
        binding.layoutDataNull.setVisibility(View.GONE);
        binding.refreshLayout.setVisibility(View.VISIBLE);
        binding.refreshLayout.finishLoadMore();
    }
    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.tv_add) {
            AppManager.getAppManager().startActivity(new Intent(this, ExaminationInfoDetailActivity.class).putExtra(BaseConfig.EXTRA_TYPE, 1));
            mOperatePopupWindow.dismiss();
        } else if (id == R.id.tv_select) {
            viewModel.getOperateTypeLiveData().postValue(1);
            mOperatePopupWindow.dismiss();
        } else if (id == R.id.tv_from_new_to_old) {
            viewModel.changeOrder(true);
            mOperatePopupWindow.dismiss();
        } else if (id == R.id.tv_from_old_to_new) {
            viewModel.changeOrder(false);
            mOperatePopupWindow.dismiss();
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mOperatePopupWindow != null) {
            mOperatePopupWindow.dismiss();
        }
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        if (isSearchLayoutVisible) {
            if (!Utils.isPointInsideView(x, y, binding.layoutSearchParameter)) {
                Utils.pullCollapse(binding.containerSearchParameter, binding.layoutSearchParameter.getMeasuredHeight(), 0);
                isSearchLayoutVisible = false;
                return true;
            }
        }
        return super.dispatchTouchEvent(event);
    }
    @Override
    public void onLeftClick(TitleBar titleBar) {
        finish();
    }
}
app/src/main/java/com/application/zhangshi_app_android/ui/function/ExaminationInfoActivityViewModel.java
New file
@@ -0,0 +1,346 @@
package com.application.zhangshi_app_android.ui.function;
import static com.android.app_base.base.BaseConfig.CODE_SUCCESS;
import android.app.Application;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.android.app_base.base.StateViewEnum;
import com.android.app_base.base.viewmodel.BaseViewModel;
import com.android.app_base.http.ResultData;
import com.android.app_base.utils.RxUtils;
import com.android.app_base.utils.Utils;
import com.application.zhangshi_app_android.bean.ExaminationInfoBean;
import com.application.zhangshi_app_android.bean.ExaminationInfoRequestBean;
import com.application.zhangshi_app_android.bean.PageResponseBean;
import com.application.zhangshi_app_android.data.DataRepository;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
/**
 * @author Ljj
 * @date 2023.10.23. 22:08
 * @desc
 */
public class ExaminationInfoActivityViewModel extends BaseViewModel<DataRepository> {
    private MutableLiveData<List<ExaminationInfoBean>> dataListLiveData;
    private MutableLiveData<List<ExaminationInfoBean>> checkListLiveData;//选中的数据
    private MutableLiveData<List<ExaminationInfoBean>> moreListLiveData;//下拉加载数据
    private MutableLiveData<ExaminationInfoRequestBean> requestBeanLiveData;//请求参数
    private MutableLiveData<List<ExaminationInfoBean>> finishDeleteListLiveData;//已经完成删除的数据,用于adapter的remove操作
    private MutableLiveData<Integer> operateTypeLiveData;//操作类型 0 选择操作 1.完成 2.删除
    public ExaminationInfoActivityViewModel(@NonNull Application application) {
        super(application);
    }
    @Override
    protected DataRepository initModel() {
        return DataRepository.getInstance();
    }
    /**
     *  获取数据
     */
    public void getExaminationInfo() {
        if (getRequestBeanLiveData().getValue() == null){
            getRequestBeanLiveData().setValue(new ExaminationInfoRequestBean());
        }
        getRequestBeanLiveData().getValue().setPageNum(1);
        model.getExaminationInfo(getRequestBeanLiveData().getValue().toMap())
                .compose(RxUtils.schedulersTransformer())
                .subscribe(new Observer<ResultData<PageResponseBean<ExaminationInfoBean>>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        addSubscribe(d);
                    }
                    @Override
                    public void onNext(ResultData<PageResponseBean<ExaminationInfoBean>> data) {
                        if (data.getCode() == CODE_SUCCESS){
                            if (data.getData().getData().isEmpty()){
                                changeStateView(StateViewEnum.DATA_NULL);
                            }else {
                                changeStateView(StateViewEnum.HIDE);
                                dataListLiveData.postValue(data.getData().getData());
                            }
                        }else {
                            messageLiveData.postValue(data.getMsg());
                        }
                    }
                    @Override
                    public void onError(Throwable e) {
                        messageLiveData.postValue(e.getMessage());
                    }
                    @Override
                    public void onComplete() {
                    }
                });
    }
    /**
     * 加载更多
     */
    public void getMoreExaminationInfo() {
        if (getRequestBeanLiveData().getValue() == null){
            getRequestBeanLiveData().setValue(new ExaminationInfoRequestBean());
        }
        getRequestBeanLiveData().getValue().setPageNum(getRequestBeanLiveData().getValue().getPageNum() + 1);
        model.getExaminationInfo(getRequestBeanLiveData().getValue().toMap())
                .compose(RxUtils.schedulersTransformer())
                .doFinally(new Action() {
                    @Override
                    public void run() throws Exception {
                        changeStateView(StateViewEnum.DATA_FINISH);
                    }
                })
                .subscribe(new Observer<ResultData<PageResponseBean<ExaminationInfoBean>>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        addSubscribe(d);
                    }
                    @Override
                    public void onNext(ResultData<PageResponseBean<ExaminationInfoBean>> data) {
                        if (data.getCode() == CODE_SUCCESS){
                            if (data.getData().getData().isEmpty()){
                                messageLiveData.postValue("没有更多数据了");
                            }else {
                                changeStateView(StateViewEnum.HIDE);
                                moreListLiveData.postValue(data.getData().getData());
                            }
                        }else {
                            messageLiveData.postValue(data.getMsg());
                        }
                    }
                    @Override
                    public void onError(Throwable e) {
                        messageLiveData.postValue(e.getMessage());
                    }
                    @Override
                    public void onComplete() {
                    }
                });
    }
    /**
     * 删除多选选中的数据
     */
    public void deleteCheckList() {
        List<ExaminationInfoBean> deleteList = getCheckListLiveData().getValue();
        if (deleteList == null){
            return;
        }
        StringBuffer sb = new StringBuffer();
        deleteList.forEach(ExaminationInfoBean -> sb.append(ExaminationInfoBean.getId()).append(","));
        sb.deleteCharAt(sb.length()-1);
        model.deleteExaminationInfo(sb.toString())
                .compose(RxUtils.schedulersTransformer())
                .subscribe(new Observer<ResultData<String>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        addSubscribe(d);
                    }
                    @Override
                    public void onNext(ResultData<String> stringResultData) {
                        if (stringResultData.getCode() == CODE_SUCCESS){
                            finishDeleteListLiveData.postValue(checkListLiveData.getValue());
                            messageLiveData.postValue("删除成功");
                            getCheckListLiveData().postValue(new ArrayList<>());
                        }else {
                            messageLiveData.postValue(stringResultData.getMsg());
                        }
                    }
                    @Override
                    public void onError(Throwable e) {
                        messageLiveData.postValue(e.getMessage());
                    }
                    @Override
                    public void onComplete() {
                    }
                });
    }
    /**
     * 删除单个数据
     */
    public void deleteItem(ExaminationInfoBean ExaminationInfoBean) {
        model.deleteExaminationInfo(String.valueOf(ExaminationInfoBean.getId()))
                .compose(RxUtils.schedulersTransformer())
                .subscribe(new Observer<ResultData<String>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        addSubscribe(d);
                    }
                    @Override
                    public void onNext(ResultData<String> stringResultData) {
                        if (stringResultData.getCode() == CODE_SUCCESS){
                            List<ExaminationInfoBean> list = new ArrayList<>();
                            list.add(ExaminationInfoBean);
                            finishDeleteListLiveData.postValue(list);
                            messageLiveData.postValue("删除成功");
                        }else {
                            messageLiveData.postValue(stringResultData.getMsg());
                        }
                    }
                    @Override
                    public void onError(Throwable e) {
                        messageLiveData.postValue(e.getMessage());
                    }
                    @Override
                    public void onComplete() {
                    }
                });
    }
    public MutableLiveData<List<ExaminationInfoBean>> getCheckListLiveData() {
        if (checkListLiveData==null){
            checkListLiveData = new MutableLiveData<>();
            checkListLiveData.postValue(new ArrayList<>());
        }
        if (checkListLiveData.getValue() == null){
            checkListLiveData.postValue(new ArrayList<>());
        }
        return checkListLiveData;
    }
    public void setCheckListLiveData(MutableLiveData<List<ExaminationInfoBean>> checkListLiveData) {
        this.checkListLiveData = checkListLiveData;
    }
    @NonNull
    public MutableLiveData<ExaminationInfoRequestBean> getRequestBeanLiveData() {
        if (requestBeanLiveData == null){
            requestBeanLiveData = new MutableLiveData<>();
        }
        if (requestBeanLiveData.getValue() == null){
            requestBeanLiveData.setValue(new ExaminationInfoRequestBean());
        }
        return requestBeanLiveData;
    }
    public void setRequestBeanLiveData(MutableLiveData<ExaminationInfoRequestBean> requestBeanLiveData) {
        this.requestBeanLiveData = requestBeanLiveData;
    }
    public MutableLiveData<List<ExaminationInfoBean>> getDataListLiveData() {
        if (dataListLiveData == null){
            dataListLiveData = new MutableLiveData<>();
        }
        return dataListLiveData;
    }
    public void setDataListLiveData(MutableLiveData<List<ExaminationInfoBean>> dataListLiveData) {
        this.dataListLiveData = dataListLiveData;
    }
    @NonNull
    public MutableLiveData<List<ExaminationInfoBean>> getMoreListLiveData() {
        if (moreListLiveData == null){
            moreListLiveData = new MutableLiveData<>();
        }
        return moreListLiveData;
    }
    public void setMoreListLiveData(MutableLiveData<List<ExaminationInfoBean>> moreListLiveData) {
        this.moreListLiveData = moreListLiveData;
    }
    @NonNull
    public MutableLiveData<Integer> getOperateTypeLiveData() {
        if (operateTypeLiveData == null){
            operateTypeLiveData = new MutableLiveData<>();
            operateTypeLiveData.setValue(0);
        }
        return operateTypeLiveData;
    }
    public void setOperateTypeLiveData(MutableLiveData<Integer> operateTypeLiveData) {
        this.operateTypeLiveData = operateTypeLiveData;
    }
    public LiveData<List<ExaminationInfoBean>> getFinishDeleteListLiveData() {
        if (finishDeleteListLiveData == null){
            finishDeleteListLiveData = new MutableLiveData<>();
        }
        return finishDeleteListLiveData;
    }
    public void setFinishDeleteListLiveData(MutableLiveData<List<ExaminationInfoBean>> finishDeleteListLiveData) {
        this.finishDeleteListLiveData = finishDeleteListLiveData;
    }
    /**
     * 改变排序
     * @param b true 降序 false 升序
     */
    public void changeOrder(boolean b) {
        List<ExaminationInfoBean> list = getDataListLiveData().getValue();
        if (list == null || list.isEmpty()){
            return;
        }
        if (b) {
            // 从新到旧,null排最后
            list.sort((o1, o2) -> {
                String happenTime1 = o1.getHappenTime();
                String happenTime2 = o2.getHappenTime();
                if (TextUtils.isEmpty(happenTime1) && TextUtils.isEmpty(happenTime2)) {
                    return 0;
                } else if (TextUtils.isEmpty(happenTime1)) {
                    return 1;
                } else if (TextUtils.isEmpty(happenTime2)) {
                    return -1;
                } else {
                    Date date1 = Utils.parseDate(happenTime1);
                    Date date2 = Utils.parseDate(happenTime2);
                    if (date1 != null && date2 != null) {
                        return date2.compareTo(date1);
                    }
                    return 0;
                }
            });
        } else  {
            // 从旧到新,null排最前
            list.sort((o1, o2) -> {
                String happenTime1 = o1.getHappenTime();
                String happenTime2 = o2.getHappenTime();
                if (TextUtils.isEmpty(happenTime1) && TextUtils.isEmpty(happenTime2)) {
                    return 0;
                } else if (TextUtils.isEmpty(happenTime1)) {
                    return -1;
                } else if (TextUtils.isEmpty(happenTime2)) {
                    return 1;
                } else {
                    Date date1 = Utils.parseDate(happenTime1);
                    Date date2 = Utils.parseDate(happenTime2);
                    if (date1 != null && date2 != null) {
                        return date1.compareTo(date2);
                    }
                    return 0;
                }
            });
        }
        getDataListLiveData().setValue(list);
    }
}
app/src/main/java/com/application/zhangshi_app_android/ui/function/ExaminationInfoDetailActivity.java
New file
@@ -0,0 +1,313 @@
package com.application.zhangshi_app_android.ui.function;
import android.app.Activity;
import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.view.View;
import android.widget.PopupWindow;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.app_base.base.BaseConfig;
import com.android.app_base.base.adapter.BaseRVAdapter;
import com.android.app_base.base.dialog.BaseDialog;
import com.android.app_base.base.dialog.UIDialog;
import com.android.app_base.base.dialog.WaitDialog;
import com.android.app_base.manager.UserManager;
import com.android.app_base.utils.GetFilePathFromUri;
import com.android.app_base.utils.ScreenSizeUtils;
import com.android.app_base.utils.Utils;
import com.application.zhangshi_app_android.BR;
import com.application.zhangshi_app_android.R;
import com.application.zhangshi_app_android.adapter.ElectronicFileAddAdapter;
import com.application.zhangshi_app_android.bean.ExaminationInfoBean;
import com.application.zhangshi_app_android.databinding.ActivityExaminationInfoDetailBinding;
import com.application.zhangshi_app_android.databinding.ActivityExaminationInfoDetailBinding;
import com.application.zhangshi_app_android.ui.DLBaseActivity;
import com.github.gzuliyujiang.wheelpicker.DatePicker;
import com.github.gzuliyujiang.wheelpicker.OptionPicker;
import com.github.gzuliyujiang.wheelpicker.contract.OnDatePickedListener;
import com.github.gzuliyujiang.wheelpicker.contract.OnOptionPickedListener;
import com.hjq.bar.TitleBar;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.interfaces.OnResultCallbackListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
/**
 * @author Ljj
 * @date 2023.10.23. 22:40
 * @desc 历年体检报告详情
 */
public class ExaminationInfoDetailActivity extends DLBaseActivity<ActivityExaminationInfoDetailBinding,ExaminationInfoDetailActivityViewModel> {
    private ElectronicFileAddAdapter adapter;
    private BaseDialog mWaitDialog;
    private ActivityResultLauncher<Intent> activityResultLauncher;
    private int type;// 0 查看可修改删除 1 新增 2 直接修改
    private PopupWindow popupWindow;
    @Override
    public int getLayoutId() {
        return R.layout.activity_examination_info_detail;
    }
    @Override
    public int getVariableId() {
        return BR.viewModel;
    }
    @Override
    public void initParam() {
        type = getIntent().getIntExtra(BaseConfig.EXTRA_TYPE,0);
        if (type == 0 || type == 2){
            ExaminationInfoBean bean = (ExaminationInfoBean) getIntent().getSerializableExtra("bean");
            if (bean !=null){
                viewModel.getBeanLiveData().setValue(bean);
            }
        }
    }
    @Override
    public void initView() {
        adapter = new ElectronicFileAddAdapter(this);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
        binding.rvImage.setLayoutManager(gridLayoutManager);
        binding.rvImage.setNestedScrollingEnabled(false);
        adapter.setItemAndAddClickListener(new ElectronicFileAddAdapter.OnItemAndAddClickListener() {
            @Override
            public void onItemClick(View v, int position) {
            }
            @Override
            public void onAddClick() {
                OptionPicker picker = getOptionPicker(Arrays.asList("图片视频","其他文件"));
                picker.setTitle("选择文件类型");
                picker.setOnOptionPickedListener(new OnOptionPickedListener() {
                    @Override
                    public void onOptionPicked(int position, Object item) {
                        if (item.equals("图片视频")) {
                            UserManager.getInstance().selectImage(getSelfActivity(), 0,9, new OnResultCallbackListener<LocalMedia>() {
                                @Override
                                public void onResult(ArrayList<LocalMedia> result) {
                                    if (result.size() == 0) return;
                                    for (LocalMedia media : result) {
                                        String path = media.getRealPath();
                                        if (path!=null){
                                            viewModel.addUploadFile(path);
                                            ExaminationInfoBean bean = viewModel.getBeanLiveData().getValue();
                                            if (bean !=null){
                                                List<String> urlList = Utils.splitString2List(bean.getUrl(),",");
                                                urlList.add(path);
                                                bean.setUrl(Utils.appendList2String(urlList,","));
                                            }
                                            viewModel.getBeanLiveData().setValue(bean);
                                        }
                                    }
                                }
                                @Override
                                public void onCancel() {
                                }
                            });
                        }else {
                            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
//                            Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                            intent.setType("*/*"); // 限制文件类型
                            intent.addCategory(Intent.CATEGORY_OPENABLE); // 添加 CATEGORY_OPENABLE 分类,告诉系统要选择的内容可以被打开,这样系统会过滤掉不能被应用打开的文件,以提供更好的用户体验。
                            intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); // 允许多选
                            activityResultLauncher.launch(intent);
                        }
                    }
                });
                picker.show();
            }
        });
        adapter.setOnChildClickListener(R.id.iv_delete, new BaseRVAdapter.OnChildClickListener() {
            @Override
            public void onChildClick(RecyclerView recyclerView, View childView, int position) {
                ExaminationInfoBean bean = viewModel.getBeanLiveData().getValue();
                if (bean !=null){
                    List<String> urlList = Utils.splitString2List(bean.getUrl(),",");
                    urlList.remove(adapter.getItem(position));
                    bean.setUrl(Utils.appendList2String(urlList,","));
                }
                adapter.removeItem(position);
                viewModel.getBeanLiveData().setValue(bean);
            }
        });
        binding.rvImage.setAdapter(adapter);
        if (type == 1){
            viewModel.getTypeLiveData().postValue(true);
            binding.ivOperate.setOnClickListener(v -> {
                viewModel.add();
            });
        }else if (type == 0){
            popupWindow = initPopUpWindow(View.inflate(this,R.layout.pop_operate_delete,null));
            popupWindow.getContentView().findViewById(R.id.tv_modify).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    viewModel.getTypeLiveData().postValue(true);
                    popupWindow.dismiss();
                }
            });
            popupWindow.getContentView().findViewById(R.id.tv_delete).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    popupWindow.dismiss();
                    new UIDialog.Builder(getSelfActivity())
                            .setTitle("您确定要删除项目吗")
                            .setContent("项目删除后将无法恢复")
                            .setConfirm("确定")
                            .setCancel("取消")
                            .setListener(new UIDialog.OnListener() {
                                @Override
                                public void onConfirm(BaseDialog dialog) {
                                    viewModel.delete();
                                }
                            })
                            .show();
                }
            });
            viewModel.getTypeLiveData().postValue(false);
        }else if (type == 2){
            viewModel.getTypeLiveData().postValue(true);
        }
        binding.etTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DatePicker picker = getDatePicker();
                picker.setTitle("选择时间");
                picker.setOnDatePickedListener(new OnDatePickedListener() {
                    @Override
                    public void onDatePicked(int year, int month, int day) {
                        String date = String.format(Locale.CHINA, "%d-%02d-%02d", year, month, day);
                        binding.etTime.setText(date);
                    }
                });
                picker.show();
            }
        });
        activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    if (result.getData() == null){
                        return;
                    }
                    // 获取选中的多个文件的 URI
                    ClipData clipData = result.getData().getClipData();
                    if (clipData != null) {
                        int itemCount = clipData.getItemCount();
                        for (int i = 0; i < itemCount; i++) {
                            Uri uri = clipData.getItemAt(i).getUri();
                            // 使用选中的文件 URI 进行后续操作,比如读取文件内容等
                            String path = GetFilePathFromUri.getFileAbsolutePath(getSelfActivity(),uri);
                            if (path!=null){
                                viewModel.addUploadFile(path);
                                ExaminationInfoBean bean = viewModel.getBeanLiveData().getValue();
                                if (bean !=null){
                                    List<String> urlList = Utils.splitString2List(bean.getUrl(),",");
                                    urlList.add(path);
                                    bean.setUrl(Utils.appendList2String(urlList,","));
                                }
                                viewModel.getBeanLiveData().setValue(bean);
                            }
                        }
                    }else {
                        // 获取选中的单个文件的 URI
                        Uri selectedFileUri = result.getData().getData();
                        String path = GetFilePathFromUri.getFileAbsolutePath(getSelfActivity(),selectedFileUri);
                        if (path!=null){
                            viewModel.addUploadFile(path);
                            ExaminationInfoBean bean = viewModel.getBeanLiveData().getValue();
                            if (bean !=null){
                                List<String> urlList = Utils.splitString2List(bean.getUrl(),",");
                                urlList.add(path);
                                bean.setUrl(Utils.appendList2String(urlList,","));
                            }
                            viewModel.getBeanLiveData().setValue(bean);
                        }
                    }
                }
            }
        });
    }
    @Override
    public void initData() {
    }
    @Override
    public void initLiveDataObserve() {
        viewModel.getBeanLiveData().observe(this,bean -> {
            if (bean!=null){
                adapter.setData(Utils.splitString2List(bean.getUrl(),","));
            }
        });
        viewModel.getTypeLiveData().observe(this,operateType -> {
            if (operateType){
                if (type == 1) {
                    binding.ivOperate.setOnClickListener(v -> {
                        viewModel.add();
                    });
                }else {
                    binding.ivOperate.setOnClickListener(v -> {
                        viewModel.update();
                    });
                }
                setIsEdited(true);
            }else {
                binding.ivOperate.setOnClickListener(v -> {
                    popupWindow.showAsDropDown(binding.ivOperate,-ScreenSizeUtils.dip2px(this,85) +binding.ivOperate.getWidth(),0);
                });
                setIsEdited(false);
            }
        });
    }
    public void setIsEdited(boolean isEdited){
        adapter.setIsEdited(isEdited);
    }
    @Override
    protected void dialogLoading() {
        if (mWaitDialog == null) {
            mWaitDialog = new WaitDialog.Builder(this)
                    // 消息文本可以不用填写
                    .setMessage("正在上传")
                    .create();
        }
        if (!mWaitDialog.isShowing()) {
            mWaitDialog.show();
        }
    }
    @Override
    protected void dialogDismiss() {
        if (mWaitDialog != null && mWaitDialog.isShowing()) {
            mWaitDialog.dismiss();
            mWaitDialog = null;
        }
    }
    @Override
    public void onLeftClick(TitleBar titleBar) {
        finish();
    }
}
app/src/main/java/com/application/zhangshi_app_android/ui/function/ExaminationInfoDetailActivityViewModel.java
New file
@@ -0,0 +1,361 @@
package com.application.zhangshi_app_android.ui.function;
import static com.android.app_base.base.BaseConfig.CODE_SUCCESS;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData;
import com.android.app_base.base.StateViewEnum;
import com.android.app_base.base.viewmodel.BaseViewModel;
import com.android.app_base.http.ResultData;
import com.android.app_base.manager.AppManager;
import com.android.app_base.utils.RxUtils;
import com.android.app_base.utils.rxbus.RxBus;
import com.application.zhangshi_app_android.bean.ExaminationInfoBean;
import com.application.zhangshi_app_android.bean.UploadFileResponseBean;
import com.application.zhangshi_app_android.data.DataRepository;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
/**
 * @author Ljj
 * @date 2023.10.23. 22:44
 * @desc 历年体检报告详情 ViewModel
 */
public class ExaminationInfoDetailActivityViewModel extends BaseViewModel<DataRepository> {
    private MutableLiveData<ExaminationInfoBean> beanLiveData;
    private MutableLiveData<Boolean> typeLiveData;//true 编辑状态 false 展示状态
    private final List<String> uploadFileList = new ArrayList<>();//需要上传的文件列表
    public ExaminationInfoDetailActivityViewModel(@NonNull Application application) {
        super(application);
    }
    @Override
    protected DataRepository initModel() {
        return DataRepository.getInstance();
    }
    /**
     * 添加
     */
    public void add() {
        if (uploadFileList.size() > 0) {
            List<Observable<String>> observables = new ArrayList<>();
            for (String path : uploadFileList) {
                File file = new File(path);
                RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
                MultipartBody.Part body = MultipartBody.Part.createFormData("uploadFile", file.getName(), requestBody);
                Observable<String> uploadObservable = model.uploadFile(body)
                        .flatMap(new Function<ResultData<UploadFileResponseBean>, ObservableSource<String>>() {
                            @Override
                            public ObservableSource<String> apply(ResultData<UploadFileResponseBean> resultData) throws Exception {
                                if (resultData.getCode() == CODE_SUCCESS) {
                                    ExaminationInfoBean bean = getBeanLiveData().getValue();
                                    if (bean != null) {
                                        String urls = bean.getUrl();
                                        //替换图片地址
                                        urls = urls.replace(path, resultData.getData().getUrl());
                                        bean.setUrl(urls);
                                        beanLiveData.postValue(bean);
                                    }
                                    return Observable.just(path);
                                } else {
                                    return Observable.error(new Exception(resultData.getMsg()));
                                }
                            }
                        });
                observables.add(uploadObservable);
            }
            Observable.zip(observables, result -> result)
                    .flatMap(new Function<Object[], Observable<ResultData<String>>>() {
                        @Override
                        public Observable<ResultData<String>> apply(Object[] objects) throws Exception {
                            //移除已经上传的文件
                            //把objects数组转换成list,然后移除
                            for (Object object : objects) {
                                uploadFileList.remove((String) object);
                            }
                            return model.addExaminationInfo(beanLiveData.getValue());
                        }
                    })
                    .doOnSubscribe(new Consumer<Disposable>() {
                        @Override
                        public void accept(Disposable disposable) throws Exception {
                            changeStateView(StateViewEnum.DIALOG_LOADING);
                        }
                    })
                    .doFinally(new Action() {
                        @Override
                        public void run() throws Exception {
                            changeStateView(StateViewEnum.DIALOG_DISMISS);
                        }
                    })
                    .compose(RxUtils.schedulersTransformer())
                    .subscribe(new Observer<ResultData<String>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            addSubscribe(d);
                        }
                        @Override
                        public void onNext(ResultData<String> stringResultData) {
                            if (stringResultData.getCode() == CODE_SUCCESS) {
                                AppManager.getAppManager().finishCurrentActivity();
                                RxBus.getInstance().post(beanLiveData.getValue());
                                messageLiveData.postValue("添加成功");
                            } else {
                                messageLiveData.postValue(stringResultData.getMsg());
                            }
                        }
                        @Override
                        public void onError(Throwable e) {
                            messageLiveData.postValue(e.getMessage());
                        }
                        @Override
                        public void onComplete() {
                        }
                    });
        }else {
            model.addExaminationInfo(beanLiveData.getValue())
                    .compose(RxUtils.schedulersTransformer())
                    .subscribe(new Observer<ResultData<String>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            addSubscribe(d);
                        }
                        @Override
                        public void onNext(ResultData<String> stringResultData) {
                            if (stringResultData.getCode() == CODE_SUCCESS){
                                AppManager.getAppManager().finishCurrentActivity();
                                RxBus.getInstance().post(beanLiveData.getValue());
                                messageLiveData.postValue("添加成功");
                            }else {
                                messageLiveData.postValue(stringResultData.getMsg());
                            }
                        }
                        @Override
                        public void onError(Throwable e) {
                            messageLiveData.postValue(e.getMessage());
                        }
                        @Override
                        public void onComplete() {
                        }
                    });
        }
    }
    /**
     * 删除
     */
    public void delete() {
        if (beanLiveData.getValue() == null){
            return;
        }
        model.deleteExaminationInfo(String.valueOf(beanLiveData.getValue().getId()))
                .compose(RxUtils.schedulersTransformer())
                .subscribe(new Observer<ResultData<String>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        addSubscribe(d);
                    }
                    @Override
                    public void onNext(ResultData<String> stringResultData) {
                        if (stringResultData.getCode() == CODE_SUCCESS){
                            AppManager.getAppManager().finishCurrentActivity();
                            RxBus.getInstance().post(beanLiveData.getValue());
                            messageLiveData.postValue("删除成功");
                        }else {
                            messageLiveData.postValue(stringResultData.getMsg());
                        }
                    }
                    @Override
                    public void onError(Throwable e) {
                        messageLiveData.postValue(e.getMessage());
                    }
                    @Override
                    public void onComplete() {
                    }
                });
    }
    /**
     * 修改
     */
    public void update() {
        if (uploadFileList.size() > 0){
            List<Observable<String>> observables = new ArrayList<>();
            for (String path : uploadFileList) {
                File file = new File(path);
                RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
                MultipartBody.Part body = MultipartBody.Part.createFormData("uploadFile", file.getName(), requestBody);
                Observable<String> uploadObservable = model.uploadFile(body)
                        .flatMap(new Function<ResultData<UploadFileResponseBean>, ObservableSource<String>>() {
                            @Override
                            public ObservableSource<String> apply(ResultData<UploadFileResponseBean> resultData) throws Exception {
                                if (resultData.getCode() == CODE_SUCCESS){
                                    ExaminationInfoBean bean = getBeanLiveData().getValue();
                                    if (bean != null){
                                        String urls = bean.getUrl();
                                        //替换图片地址
                                        urls = urls.replace(path,resultData.getData().getUrl());
                                        bean.setUrl(urls);
                                        beanLiveData.postValue(bean);
                                    }
                                    return Observable.just(path);
                                }else {
                                    return Observable.error(new Exception(resultData.getMsg()));
                                }
                            }
                        });
                observables.add(uploadObservable);
            }
            Observable.zip(observables,result -> result)
                    .flatMap(new Function<Object[], Observable<ResultData<String>>>() {
                        @Override
                        public Observable<ResultData<String>> apply(Object[] objects) throws Exception {
                            //移除已经上传的文件
                            //把objects数组转换成list,然后移除
                            for (Object object : objects) {
                                uploadFileList.remove((String) object);
                            }
                            return model.updateExaminationInfo(beanLiveData.getValue());
                        }
                    })
                    .doOnSubscribe(new Consumer<Disposable>() {
                        @Override
                        public void accept(Disposable disposable) throws Exception {
                            changeStateView(StateViewEnum.DIALOG_LOADING);
                        }
                    })
                    .doFinally(new Action() {
                        @Override
                        public void run() throws Exception {
                            changeStateView(StateViewEnum.DIALOG_DISMISS);
                        }
                    })
                    .compose(RxUtils.schedulersTransformer())
                    .subscribe(new Observer<ResultData<String>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            addSubscribe(d);
                        }
                        @Override
                        public void onNext(ResultData<String> stringResultData) {
                            if (stringResultData.getCode() == CODE_SUCCESS){
                                AppManager.getAppManager().finishCurrentActivity();
                                RxBus.getInstance().post(beanLiveData.getValue());
                                messageLiveData.postValue("修改成功");
                            }else {
                                messageLiveData.postValue(stringResultData.getMsg());
                            }
                        }
                        @Override
                        public void onError(Throwable e) {
                            messageLiveData.postValue(e.getMessage());
                        }
                        @Override
                        public void onComplete() {
                        }
                    });
        }else {
            model.updateExaminationInfo(beanLiveData.getValue())
                    .compose(RxUtils.schedulersTransformer())
                    .subscribe(new Observer<ResultData<String>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            addSubscribe(d);
                        }
                        @Override
                        public void onNext(ResultData<String> stringResultData) {
                            if (stringResultData.getCode() == CODE_SUCCESS){
                                AppManager.getAppManager().finishCurrentActivity();
                                RxBus.getInstance().post(beanLiveData.getValue());
                                messageLiveData.postValue("修改成功");
                            }else {
                                messageLiveData.postValue(stringResultData.getMsg());
                            }
                        }
                        @Override
                        public void onError(Throwable e) {
                            messageLiveData.postValue(e.getMessage());
                        }
                        @Override
                        public void onComplete() {
                        }
                    });
        }
    }
    public MutableLiveData<Boolean> getTypeLiveData() {
        if (typeLiveData == null){
            typeLiveData = new MutableLiveData<>();
        }
        return typeLiveData;
    }
    public void setTypeLiveData(MutableLiveData<Boolean> typeLiveData) {
        this.typeLiveData = typeLiveData;
    }
    public MutableLiveData<ExaminationInfoBean> getBeanLiveData() {
        if (beanLiveData == null) {
            beanLiveData = new MutableLiveData<>();
        }
        if (beanLiveData.getValue() == null){
            beanLiveData.setValue(new ExaminationInfoBean());
        }
        return beanLiveData;
    }
    public void setBeanLiveData(MutableLiveData<ExaminationInfoBean> beanLiveData) {
        this.beanLiveData = beanLiveData;
    }
    public List<String> getUploadFileList() {
        return uploadFileList;
    }
    public void addUploadFile(String url) {
        uploadFileList.add(url);
    }
}
app/src/main/java/com/application/zhangshi_app_android/ui/function/FamilyAssetsActivityViewModel.java
@@ -180,7 +180,6 @@
        if (list == null || list.isEmpty()){
            return;
        }
        System.out.println(dataListLiveData.getValue().size());
        if (type == 0) {
            // 从新到旧,null排最后
            list.sort((o1, o2) -> {
app/src/main/java/com/application/zhangshi_app_android/ui/function/FunctionFragment.java
@@ -122,7 +122,7 @@
            AppManager.getAppManager().startActivity(MarriageActivity.class);
        });
        binding.layoutHealthCare.setOnClickListener(v->{
            AppManager.getAppManager().startActivity(HealthCareActivity.class);
            AppManager.getAppManager().startActivity(AnnualHealthStatusActivity.class);
        });
        binding.layoutPrivacy.setOnClickListener(v->{
            AppManager.getAppManager().startActivity(PrivacyActivity.class);
app/src/main/java/com/application/zhangshi_app_android/ui/function/HealthCareActivity.java
@@ -26,6 +26,7 @@
import com.github.gzuliyujiang.wheelpicker.OptionPicker;
import com.github.gzuliyujiang.wheelpicker.contract.OnOptionPickedListener;
import com.google.android.material.tabs.TabLayout;
import com.hjq.bar.TitleBar;
import java.util.Arrays;
import java.util.List;
@@ -58,14 +59,6 @@
    public void initView() {
        View view = View.inflate(this,R.layout.pop_annual_health_status,null);
        popupWindow = initPopUpWindow(view);
        view.findViewById(R.id.tv_annual_health_status).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popupWindow.dismiss();
                AppManager.getAppManager().startActivity(AnnualHealthStatusActivity.class);
            }
        });
        view.findViewById(R.id.tv_edit).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
@@ -124,7 +117,6 @@
    @Override
    public void initLiveDataObserve() {
        System.out.println("我"+binding.ivA.isClickable());
        viewModel.getIsLifeHabitsExpendedLiveData().observe(this, aBoolean -> {
            if (aBoolean){
                binding.layoutTitleLifeHabits.setOnClickListener(view -> {
@@ -179,7 +171,7 @@
                    binding.ivOperate.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            popupWindow.showAsDropDown(binding.ivOperate,-ScreenSizeUtils.dip2px(HealthCareActivity.this,118) +binding.ivOperate.getWidth(),0);
                            popupWindow.showAsDropDown(binding.ivOperate,-ScreenSizeUtils.dip2px(HealthCareActivity.this,85) +binding.ivOperate.getWidth(),0);
                        }
                    });
                }
@@ -288,4 +280,8 @@
        animator.start();
    }
    @Override
    public void onLeftClick(TitleBar titleBar) {
        finish();
    }
}
app/src/main/java/com/application/zhangshi_app_android/ui/function/ImageCarouselFragment.java
@@ -6,6 +6,7 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.android.app_base.base.BaseConfig;
import com.android.app_base.base.view.BaseFragment;
import com.android.app_base.base.viewmodel.BaseViewModel;
import com.android.app_base.utils.GlideUtil;
@@ -118,7 +119,13 @@
        adapter = new BannerImageAdapter<BannerBean>(chooseList) {
            @Override
            public void onBindView(BannerImageHolder holder, BannerBean data, int position, int size) {
                GlideUtil.loadImage(data.getUrl(), holder.imageView);
                String url = data.getUrl();
                if (url.contains("profile/upload")) {//如果是上传到服务器的图片
                    //只取profile/upload以后的部分
                    url = url.substring(url.indexOf("profile/upload"));
                    url = BaseConfig.BASE_URL_DOMAIN + "/" + url;
                }
                GlideUtil.loadImage(url, holder.imageView);
            }
            @Override
app/src/main/java/com/application/zhangshi_app_android/ui/function/TourismExperienceActivityViewModel.java
@@ -60,13 +60,13 @@
            getRequestBeanLiveData().setValue(new TourismExperienceRequestBean());
        }
        model.getTourismExperience(getRequestBeanLiveData().getValue().toMap())
                .compose(RxUtils.schedulersTransformer())
                .doFinally(new Action() {
                    @Override
                    public void run() throws Exception {
                        changeStateView(StateViewEnum.DATA_FINISH);
                    }
                })
                .compose(RxUtils.schedulersTransformer())
                .subscribe(new Observer<ResultData<List<TourismExperienceBean>>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
app/src/main/java/com/application/zhangshi_app_android/ui/function/VideoCarouselFragment.java
@@ -5,6 +5,7 @@
import androidx.viewpager2.widget.ViewPager2;
import com.android.app_base.base.BaseConfig;
import com.android.app_base.base.adapter.BaseVp2FragmentAdapter;
import com.android.app_base.base.view.BaseFragment;
import com.application.zhangshi_app_android.R;
@@ -67,7 +68,6 @@
            public void onPageSelected(int position) {
                super.onPageSelected(position);
                if (adapter.getFragment(position) != null){
                    System.out.println("onPageSelected:"+position);
                    adapter.getFragment(position).startPlay();
                }
            }
app/src/main/java/com/application/zhangshi_app_android/ui/function/VideoFragment.java
@@ -8,6 +8,7 @@
import androidx.annotation.NonNull;
import com.android.app_base.base.BaseConfig;
import com.android.app_base.base.view.BaseFragment;
import com.android.app_base.utils.GlideUtil;
import com.application.zhangshi_app_android.R;
@@ -38,10 +39,15 @@
    public VideoFragment() {
    }
    public static VideoFragment newInstance(String playUrl) {
    public static VideoFragment newInstance(String url) {
        VideoFragment fragment = new VideoFragment();
        if (url.contains("profile/upload")) {//如果是上传到服务器的图片
            //只取profile/upload以后的部分
            url = url.substring(url.indexOf("profile/upload"));
            url = BaseConfig.BASE_URL_DOMAIN + "/" + url;
        }
        Bundle args = new Bundle();
        args.putSerializable("playUrl", playUrl);
        args.putSerializable("playUrl", url);
        fragment.setArguments(args);
        return fragment;
    }
app/src/main/java/com/application/zhangshi_app_android/ui/home/HomeFragment.java
@@ -68,13 +68,14 @@
        });
        binding.scrollHomeMindMapLayout.setOnItemClickListener(new HomeMindMapLayout.OnItemClickListener() {
            @Override
            public void onItemClick(View view, HomeRootBean bean) {
            public void onItemClick(View view, HomeRootBean bean,boolean isFamily) {
                View contentView;
                if (bean.getSpouse()!=null) {
                    bean.getSpouse().setSpouse(bean);
                    PopBasicInformationDoubleBinding binding= DataBindingUtil.inflate(getLayoutInflater(),R.layout.pop_basic_information_double,null,false);
                    binding.setSelfBean(bean);
                    binding.setSpouseBean(bean.getSpouse());
                    binding.setIsFamily(isFamily);
                    contentView = binding.getRoot();
                }else {
                    PopBasicInformationSingleBinding binding = DataBindingUtil.inflate(getLayoutInflater(),R.layout.pop_basic_information_single,null,false);
app/src/main/java/com/application/zhangshi_app_android/ui/main/MainActivity.java
@@ -28,7 +28,6 @@
import com.application.zhangshi_app_android.bean.UpdateVersionBean;
import com.application.zhangshi_app_android.databinding.ActivityMainBinding;
import com.application.zhangshi_app_android.ui.dialog.UpdateDialog;
import com.application.zhangshi_app_android.ui.dialog.VersionUpdateDialog;
import com.application.zhangshi_app_android.ui.function.FunctionFragment;
import com.application.zhangshi_app_android.ui.home.HomeFragment;
import com.application.zhangshi_app_android.ui.personal_center.PersonalCenterFragment;
@@ -151,6 +150,31 @@
    }
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        switchFragment(mPagerAdapter.getFragmentIndex((Class<? extends Fragment>) intent.getSerializableExtra(INTENT_KEY_IN_FRAGMENT_CLASS)));
    }
    private void switchFragment(int fragmentIndex) {
        if (fragmentIndex == -1) {
            return;
        }
        switch (fragmentIndex) {
            case 0:
            case 1:
            case 2:
            case 3:
                binding.mainVp.setCurrentItem(fragmentIndex);
                binding.mainBnv.setSelectedItemId(binding.mainBnv.getMenu().getItem(fragmentIndex).getItemId());
                break;
            default:
                break;
        }
    }
    @Override
    protected void onDestroy() {
        binding.mainVp.setAdapter(null);
        binding.mainBnv.setOnItemSelectedListener(null);
@@ -175,7 +199,7 @@
        start(context, HomeFragment.class);
    }
    public static void start(Context context, Class<? extends BaseFragment> fragmentClass) {
    public static void start(Context context, Class<? extends Fragment> fragmentClass) {
        Intent intent = new Intent(context, MainActivity.class);
        intent.putExtra(INTENT_KEY_IN_FRAGMENT_CLASS, fragmentClass);
        if (!(context instanceof Activity)) {
app/src/main/java/com/application/zhangshi_app_android/widget/DoubleNode.java
@@ -25,6 +25,7 @@
    public DoubleNode(Context context,HomeRootBean member) {
        super(context,member);
        member.getSpouse().setSpouse(member);
        initView();
        //双亲节点 前后路径长度 有两倍的 pathLength
        if (member.getIdentity() > 1 && member.getChildList() != null && member.getChildList().size() > 0){
            //非 第一代 且 有子代, 节点宽度 = view宽度 + 前后路径长度 + 展开按钮宽度
@@ -41,7 +42,6 @@
        }
        //双亲节点 高度 = view高度 + 配偶view高度 + 配偶view上下间距
        height = getItemViewHeight() * 2 + spouseMargin;
        initView();
    }
    private void initView() {
@@ -89,8 +89,10 @@
        } else {
            viewLeft = left;
        }
        memberItemView.setX(viewLeft);
        memberItemView.setY(centerY - memberItemView.getMeasuredHeight() - spouseMargin/2f);
        viewRight = viewLeft + memberItemView.getMeasuredWidth();
        spouseView.setX(viewLeft);
@@ -241,4 +243,19 @@
        forkPathList.add(path);
    }
    @Override
    public int getItemViewWidth() {
        if (memberItemView != null){
            return memberItemView.getMeasuredWidth();
        }
        return 0;
    }
    @Override
    public int getItemViewHeight() {
        if (memberItemView != null){
            return memberItemView.getMeasuredHeight();
        }
        return 0;
    }
}
app/src/main/java/com/application/zhangshi_app_android/widget/HomeMindMapLayout.java
@@ -72,7 +72,7 @@
    private void setRootMemberReal(HomeRootBean root) {
        this.rootMember = root;
        if (rootMember != null) { // 绘制根节点,在竖直方向上居中
        if (rootMember != null) { // 绘制根节点
            if (rootMember.getSpouse() == null){
                rootNode = new SimpleNode(getContext(),rootMember);
            }else {
@@ -173,7 +173,7 @@
    }
    public interface OnItemClickListener{
        void onItemClick(View view,HomeRootBean member);
        void onItemClick(View view,HomeRootBean member,boolean isFamily);
    }
}
app/src/main/java/com/application/zhangshi_app_android/widget/Node.java
@@ -12,12 +12,15 @@
import android.widget.TextView;
import androidx.constraintlayout.utils.widget.ImageFilterView;
import androidx.core.content.res.ResourcesCompat;
import androidx.databinding.DataBindingUtil;
import com.android.app_base.manager.AppManager;
import com.android.app_base.utils.GlideUtil;
import com.android.app_base.utils.ScreenSizeUtils;
import com.application.zhangshi_app_android.R;
import com.application.zhangshi_app_android.bean.HomeRootBean;
import com.application.zhangshi_app_android.databinding.ItemFamilyMemberBinding;
import java.util.ArrayList;
import java.util.LinkedList;
@@ -100,7 +103,7 @@
     * 递归设置所有节点的位置
     * @param topNode 顶部节点,这颗节点树的最上边的节点
     * @param rootNode 根节点,这颗节点树的根节点
     *                startNode 必须是 topNode 祖先节点
     *                rootNode 必须是 topNode 祖先节点
     * @param x 整颗节点树的x坐标
     * @param y 整颗节点树的y坐标
     */
@@ -189,6 +192,7 @@
    // 设置对应类型节点的位置 由子类实现
    protected abstract void setViewPosition(int x, int centerY);
    // 设置分叉节点的位置 由子类实现,必须先setViewPosition才能调用
    protected abstract void setForkYList(List<Integer> yList);
    /**
@@ -200,45 +204,39 @@
    protected View createItemView(HomeRootBean bean,boolean isFamily){
        // 使用布局填充器加载节点布局
        LayoutInflater inflater = LayoutInflater.from(context);
        View familyMemberView = inflater.inflate(R.layout.item_family_member, null, false);
        familyMemberView.measure(View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST),
                View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST));
        ItemFamilyMemberBinding binding = DataBindingUtil.inflate(inflater, R.layout.item_family_member, null, false);
        View familyMemberView = binding.getRoot();
        // 防止addView时,所有这里创建的view的高宽被限制成一样的
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        familyMemberView.setLayoutParams(params);
        if (bean == null) {
            return familyMemberView;
        }
        // 获取布局中的组件
        TextView tv_generation = familyMemberView.findViewById(R.id.tv_generation);
        ImageFilterView iv_avatar = familyMemberView.findViewById(R.id.iv_avatar);
        TextView tv_name = familyMemberView.findViewById(R.id.tv_name);
        if (!isFamily){
            tv_name.setTextColor(Color.parseColor("#FF8296C5"));
            tv_name.setTypeface(Typeface.DEFAULT);
        }
        // 设置节点内容
        tv_generation.setText(String.valueOf(bean.getIdentity()));
        if (bean.getImg() != null) {
            GlideUtil.loadImage(bean.getImg(), iv_avatar);
        }
        tv_name.setText(bean.getNickName());
        tv_name.setSelected(true);
        familyMemberView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onItemClickListener != null){
                    onItemClickListener.onItemClick(familyMemberView,bean);
                    onItemClickListener.onItemClick(familyMemberView,bean,isFamily);
                }
            }
        });
        if (bean != null) {
            binding.setBean(bean);
            if (!isFamily){
                binding.tvName.setTextColor(Color.parseColor("#FF8296C5"));
                //获取字体
                Typeface typeface = ResourcesCompat.getFont(context, com.android.app_base.R.font.roboto_regular);
                binding.tvName.setTypeface(typeface);
            }
            // 使用databinding无法测量view的带内容的准确宽高,所以这里手动设置一下
            binding.tvGeneration.setText(bean.getIdentity()+"");
        }
        familyMemberView.measure(View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST),
                View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST));
        return familyMemberView;
    }
    protected ImageView createExpandIconView() {
        ImageView expandView = new ImageView(AppManager.getAppManager().currentActivity());
        ImageView expandView = new ImageView(context);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(pathLength,pathLength);
        expandView.setLayoutParams(params);
        int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(pathLength, View.MeasureSpec.EXACTLY);
@@ -468,15 +466,11 @@
    }
    // 获取 每个 itemView 的宽度
    public int getItemViewWidth(){
        View itemView =  createItemView(null,false);
        return itemView.getMeasuredWidth();
    }
    public abstract int getItemViewWidth();
    // 获取 每个 itemView 的高度
    public int getItemViewHeight(){
        View itemView =  createItemView(null,false);
        return itemView.getMeasuredHeight();
    }
    public abstract int getItemViewHeight();
    //获取展开按钮的宽度
    public int getExpandIconWidth(){
        ImageView expandIconView = createExpandIconView();
app/src/main/java/com/application/zhangshi_app_android/widget/SimpleNode.java
@@ -23,9 +23,12 @@
    public SimpleNode(Context context,HomeRootBean member) {
        super(context,member);
        initView();
        if (member.getIdentity() > 1 && member.getChildList() != null && member.getChildList().size() > 0){
            //非 第一代 且 有子代, 节点宽度 = view宽度 + 前后路径长度 + 展开按钮宽度
            width = pathLength + getItemViewWidth() + pathLength  + getExpandIconWidth();
            width = pathLength + memberItemView.getMeasuredWidth() + pathLength  + expandIconView.getMeasuredWidth();
        }else if (member.getIdentity() > 1 && (member.getChildList() == null || member.getChildList().size() == 0)) {
            //非 第一代 且 无子代, 节点宽度 = view宽度 + 前路径长度
            width = getItemViewWidth() + pathLength;
@@ -38,7 +41,6 @@
        }
        //单亲节点 高度 = view高度
        height = getItemViewHeight();
        initView();
    }
    private void initView() {
@@ -178,4 +180,20 @@
        }
        forkPathList.add(path);
    }
    @Override
    public int getItemViewWidth() {
        if (memberItemView != null){
            return memberItemView.getMeasuredWidth();
        }
        return 0;
    }
    @Override
    public int getItemViewHeight() {
        if (memberItemView != null){
            return memberItemView.getMeasuredHeight();
        }
        return 0;
    }
}
app/src/main/res/drawable/shape_gradient_browser_progress.xml
New file
@@ -0,0 +1,22 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape>
            <gradient
                android:centerColor="@color/transparent"
                android:endColor="@color/transparent"
                android:startColor="@color/transparent" />
        </shape>
    </item>
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <gradient
                    android:centerColor="#5A8DDF"
                    android:endColor="#AA5A8DDF"
                    android:startColor="@color/transparent" />
            </shape>
        </clip>
    </item>
</layer-list>
app/src/main/res/layout/activity_annual_health_status.xml
@@ -20,7 +20,6 @@
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:leftIcon="@drawable/ic_back"
            >
            <FrameLayout
                android:layout_width="24dp"
@@ -49,7 +48,7 @@
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="16dp"
                    android:text="体检或看病"
                    android:text="就医信息"
                    android:layout_weight="1"
                    android:textColor="@color/white"
                    android:textSize="20sp"
@@ -91,7 +90,7 @@
                    android:imeOptions="actionSearch"
                    android:text=""
                    android:singleLine="true"
                    android:hint="在“年度健康情况”内搜索"
                    android:hint="在“就医信息”内搜索"
                    android:focusable="false"
                    android:clickable="false"
                    android:editable="false"
app/src/main/res/layout/activity_annual_health_status_detail.xml
@@ -18,7 +18,7 @@
        <com.android.app_base.widget.ExtendTitleBar
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:title="@{viewModel.beanLiveData.id==0?`新建体检或看病`:viewModel.beanLiveData.title}"
            app:title="@{viewModel.beanLiveData.id==-1?`新建就医信息`:viewModel.beanLiveData.title}"
            app:titleGravity="left"
            app:leftIcon="@drawable/ic_back"
            >
@@ -43,7 +43,7 @@
            >
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingHorizontal="20dp"
                android:paddingBottom="20dp"
@@ -55,13 +55,13 @@
                    android:text="序号"
                    android:textColor="#767375"
                    android:textSize="12sp"
                    android:visibility="@{viewModel.typeLiveData}"
                    android:visibility="@{viewModel.beanLiveData.id!=-1?true:false}"
                    />
                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:visibility="@{viewModel.typeLiveData}"
                    android:visibility="@{viewModel.beanLiveData.id!=-1?true:false}"
                    >
                    <EditText
                        android:id="@+id/et_id"
app/src/main/res/layout/activity_browser.xml
New file
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
    <data>
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <com.hjq.bar.TitleBar
            android:id="@+id/tb_browser_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:leftIcon="@drawable/ic_back"
            />
        <ProgressBar
            android:id="@+id/pb_browser_progress"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="3dp"
            android:progressDrawable="@drawable/shape_gradient_browser_progress"
            android:visibility="gone" />
        <com.scwang.smart.refresh.layout.SmartRefreshLayout
            android:id="@+id/sl_browser_refresh"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:srlEnableHeaderTranslationContent="false"
            app:srlEnableLoadMore="false"
            app:srlEnablePreviewInEditMode="false"
            app:srlPrimaryColor="#444444">
            <com.scwang.smart.refresh.header.MaterialHeader
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                />
            <WebView
                android:id="@+id/wv_browser_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
            <com.scwang.smart.refresh.footer.BallPulseFooter
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        </com.scwang.smart.refresh.layout.SmartRefreshLayout>
    </LinearLayout>
</layout>
app/src/main/res/layout/activity_examination_info.xml
New file
@@ -0,0 +1,318 @@
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
    <data>
        <variable
            name="viewModel"
            type="com.application.zhangshi_app_android.ui.function.ExaminationInfoActivityViewModel" />
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/color_normal_background"
        >
        <com.android.app_base.widget.ExtendTitleBar
            android:id="@+id/titleBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:leftIcon="@drawable/ic_back"
            >
            <FrameLayout
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:layout_marginHorizontal="16dp"
                android:layout_gravity="center_vertical|end"
                >
                <ImageView
                    android:id="@+id/iv_operate"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:background="@drawable/ic_operate"
                    />
            </FrameLayout>
            <LinearLayout
                android:id="@+id/layout_default"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginHorizontal="56dp"
                android:gravity="center_vertical"
                >
                <TextView
                    android:id="@+id/tv_title"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="16dp"
                    android:text="历年体检信息"
                    android:layout_weight="1"
                    android:textColor="@color/white"
                    android:textSize="20sp"
                    />
                <ImageView
                    android:id="@+id/iv_search_default"
                    android:layout_width="24dp"
                    android:layout_height="24dp"
                    android:background="@drawable/ic_search"
                    />
            </LinearLayout>
            <LinearLayout
                android:id="@+id/layout_search"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginVertical="4dp"
                android:layout_marginHorizontal="56dp"
                android:gravity="center_vertical"
                android:background="@color/white"
                android:paddingHorizontal="5dp"
                android:visibility="gone"
                >
                <ImageView
                    android:id="@+id/iv_search"
                    android:layout_width="24dp"
                    android:layout_height="24dp"
                    android:background="@drawable/ic_search_gray"
                    />
                <EditText
                    android:id="@+id/et_search"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:layout_marginStart="5dp"
                    android:textSize="14sp"
                    android:textColor="#61000000"
                    android:background="@null"
                    android:imeOptions="actionSearch"
                    android:text=""
                    android:singleLine="true"
                    android:hint="在“历年体检信息”内搜索"
                    android:focusable="false"
                    android:clickable="false"
                    android:editable="false"
                    />
                <ImageView
                    android:id="@+id/iv_search_type"
                    android:layout_width="24dp"
                    android:layout_height="24dp"
                    android:background="@drawable/ic_search_by"
                    />
            </LinearLayout>
        </com.android.app_base.widget.ExtendTitleBar>
        <LinearLayout
            android:id="@+id/layout_data_null"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:gravity="center"
            android:visibility="gone"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/titleBar">
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/img_data_null"
                />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="18dp"
                android:text="暂时还没有数据哦~\n点击”+”立即创建"
                android:textSize="14sp"
                android:textColor="#73000000"
                />
        </LinearLayout>
        <com.scwang.smart.refresh.layout.SmartRefreshLayout
            android:id="@+id/refreshLayout"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/titleBar"
            >
            <com.scwang.smart.refresh.header.MaterialHeader
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                />
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recyclerView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:itemCount="20"
                tools:listitem="@layout/item_examination_info" />
            <com.scwang.smart.refresh.footer.BallPulseFooter
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        </com.scwang.smart.refresh.layout.SmartRefreshLayout>
        <RelativeLayout
            android:id="@+id/container_search_parameter"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintTop_toBottomOf="@id/titleBar"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginTop="-4dp"
            tools:layout_height="wrap_content"
            >
            <LinearLayout
                android:id="@+id/layout_search_parameter"
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/white"
                android:layout_marginHorizontal="56dp"
                android:paddingEnd="12dp"
                android:paddingStart="5dp"
                >
                <View
                    android:layout_width="match_parent"
                    android:layout_height="0.5dp"
                    android:background="#FF939393" />
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="40dp"
                    android:gravity="center">
                    <androidx.appcompat.widget.AppCompatTextView
                        android:layout_width="0dp"
                        android:layout_weight="1"
                        android:layout_height="match_parent"
                        android:text="年度报告"
                        android:textColor="#FF333333"
                        android:textSize="14sp"
                        android:gravity="center"
                        android:maxLines="1"
                        app:autoSizeTextType="uniform"
                        app:autoSizeMinTextSize="8sp"
                        app:autoSizeMaxTextSize="14sp"
                        />
                    <com.android.app_base.widget.ClearEditText
                        android:layout_width="0dp"
                        android:layout_weight="4"
                        android:layout_height="wrap_content"
                        android:background="@null"
                        android:inputType="text"
                        android:layout_marginStart="6dp"
                        android:text="@={viewModel.requestBeanLiveData.report}"
                        android:hint="请输入年度报告"
                        android:textColorHint="#61000000"
                        android:textColor="#FF333333"
                        android:textSize="14sp"
                        android:maxLines="1"
                        app:autoSizeTextType="uniform"
                        app:autoSizeMinTextSize="8sp"
                        app:autoSizeMaxTextSize="14sp"
                        app:background="@drawable/ic_clear"
                        />
                </LinearLayout>
                <View
                    android:layout_width="match_parent"
                    android:layout_height="0.3dp"
                    android:background="#FF939393" />
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="40dp"
                    android:gravity="center"
                    >
                    <androidx.appcompat.widget.AppCompatTextView
                        android:layout_width="0dp"
                        android:layout_weight="1"
                        android:layout_height="wrap_content"
                        android:text="时间"
                        android:textColor="#FF333333"
                        android:textSize="14sp"
                        android:gravity="center"
                        android:maxLines="1"
                        app:autoSizeTextType="uniform"
                        app:autoSizeMinTextSize="8sp"
                        app:autoSizeMaxTextSize="14sp"
                        />
                    <LinearLayout
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="4"
                        android:gravity="center"
                        >
                        <androidx.appcompat.widget.AppCompatTextView
                            android:id="@+id/et_start_time"
                            android:layout_width="0dp"
                            android:layout_weight="1"
                            android:layout_height="wrap_content"
                            android:gravity="center"
                            android:layout_marginStart="6dp"
                            android:text="@={viewModel.requestBeanLiveData.happenStartTime}"
                            android:hint="开始时间"
                            android:textColorHint="#61000000"
                            android:textColor="#FF333333"
                            android:textSize="14sp"
                            android:maxLines="1"
                            android:lines="1"
                            app:autoSizeTextType="uniform"
                            app:autoSizeMinTextSize="8sp"
                            app:autoSizeMaxTextSize="14sp"
                            tools:text="2022-01-01"
                            />
                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="—"
                            />
                        <androidx.appcompat.widget.AppCompatTextView
                            android:id="@+id/et_end_time"
                            android:layout_width="0dp"
                            android:layout_weight="1"
                            android:gravity="center"
                            android:layout_height="wrap_content"
                            android:text="@={viewModel.requestBeanLiveData.happenEndTime}"
                            android:hint="结束时间"
                            android:textColorHint="#61000000"
                            android:textColor="#FF333333"
                            android:textSize="14sp"
                            android:maxLines="1"
                            app:autoSizeTextType="uniform"
                            app:autoSizeMinTextSize="8sp"
                            app:autoSizeMaxTextSize="14sp"
                            tools:text="2022-01-01"
                            />
                        <ImageView
                            android:id="@+id/iv_time_clear"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:background="@drawable/ic_clear"
                            android:visibility="invisible"
                            />
                    </LinearLayout>
                </LinearLayout>
            </LinearLayout>
        </RelativeLayout>
        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab_add"
            android:layout_width="56dp"
            android:layout_height="56dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginEnd="25dp"
            android:layout_marginBottom="@dimen/dp_44"
            android:src="@drawable/ic_add"
            app:fabCustomSize="56dp"
            />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
app/src/main/res/layout/activity_examination_info_detail.xml
New file
@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
    <data>
        <variable
            name="viewModel"
            type="com.application.zhangshi_app_android.ui.function.ExaminationInfoDetailActivityViewModel" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/color_normal_background"
        android:orientation="vertical">
        <com.android.app_base.widget.ExtendTitleBar
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:title="历年体检信息"
            app:titleGravity="left"
            app:leftIcon="@drawable/ic_back"
            >
            <FrameLayout
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:layout_marginHorizontal="16dp"
                android:layout_gravity="center_vertical|end"
                >
                <ImageView
                    android:id="@+id/iv_operate"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:background="@{viewModel.typeLiveData?@drawable/ic_operate_finish:@drawable/ic_operate}" />
            </FrameLayout>
        </com.android.app_base.widget.ExtendTitleBar>
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            >
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingHorizontal="20dp"
                android:paddingBottom="20dp"
                >
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_marginTop="10dp"
                    android:layout_height="wrap_content"
                    android:text="年度报告(注意事项描述)"
                    android:textColor="#767375"
                    android:textSize="12sp"
                    />
                <EditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="2dp"
                    android:inputType="text"
                    android:textColorHint="#6b000000"
                    android:hint="@{viewModel.typeLiveData?`请输入年度报告`:``}"
                    android:text="@={viewModel.beanLiveData.report}"
                    android:textColor="#DE000000"
                    android:textSize="16sp"
                    android:enabled="@{viewModel.typeLiveData}"
                    />
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_marginTop="10dp"
                    android:layout_height="wrap_content"
                    android:text="体检时间"
                    android:textColor="#767375"
                    android:textSize="12sp"
                    />
                <EditText
                    android:id="@+id/et_time"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="2dp"
                    android:inputType="text"
                    android:textColorHint="#6b000000"
                    android:hint="@{viewModel.typeLiveData?`请选择时间`:``}"
                    android:textColor="#DE000000"
                    android:text="@={viewModel.beanLiveData.happenTime}"
                    android:textSize="16sp"
                    app:isEditable="@{false}"
                    android:enabled="@{viewModel.typeLiveData}"
                    />
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_marginTop="10dp"
                    android:layout_height="wrap_content"
                    android:text="电子文件"
                    android:textColor="#767375"
                    android:textSize="12sp"
                    />
                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@drawable/shape_6b0000_stroke"
                    >
                    <com.android.app_base.widget.WrapRecyclerView
                        android:id="@+id/rv_image"
                        android:orientation="vertical"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginBottom="10dp"
                        android:layout_marginTop="2sp"
                        android:paddingStart="10dp"
                        android:paddingEnd="5dp"
                        android:paddingVertical="10dp"
                        />
                </RelativeLayout>
            </LinearLayout>
        </ScrollView>
    </LinearLayout>
</layout>
app/src/main/res/layout/activity_growth_experience.xml
@@ -603,7 +603,7 @@
                                android:layout_width="0dp"
                                android:layout_height="wrap_content"
                                android:layout_weight="1"
                                android:text="持有境证件情况"
                                android:text="持有证件情况"
                                android:textColor="#ff000000"
                                android:textSize="20sp"
                                android:textStyle="bold"
app/src/main/res/layout/activity_health_care.xml
@@ -24,6 +24,7 @@
            app:layout_constraintTop_toTopOf="parent"
            app:title="健康保健"
            app:titleGravity="left"
            app:leftIcon="@drawable/ic_back"
            >
            <FrameLayout
app/src/main/res/layout/item_examination_info.xml
New file
@@ -0,0 +1,181 @@
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
    <data>
        <variable
            name="bean"
            type="com.application.zhangshi_app_android.bean.ExaminationInfoBean" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <androidx.cardview.widget.CardView
            android:id="@+id/cardView"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_margin="@dimen/dp_2"
            app:cardCornerRadius="@dimen/dp_10"
            app:cardBackgroundColor="@color/color_card_pink"
            tools:layout_height="wrap_content"
            >
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                >
                <androidx.constraintlayout.widget.ConstraintLayout
                    android:id="@+id/layout_title"
                    android:layout_width="match_parent"
                    android:layout_height="40dp"
                    android:gravity="center_vertical"
                    >
                    <CheckBox
                        android:id="@+id/checkbox"
                        android:layout_width="18dp"
                        android:layout_height="18dp"
                        android:layout_marginStart="3dp"
                        android:layout_centerVertical="true"
                        android:button="@drawable/selector_checkbox"
                        android:background="?selectableItemBackgroundBorderless"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:layout_constraintBottom_toBottomOf="parent"
                        />
                    <TextView
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_centerVertical="true"
                        android:ellipsize="end"
                        android:maxLines="1"
                        android:text="@{bean.report}"
                        android:textColor="@color/black"
                        android:textSize="16sp"
                        android:layout_marginStart="24dp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:layout_constraintWidth_percent="0.5"
                        tools:text="张氏App立项" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textSize="16sp"
                        android:textColor="@color/black"
                        android:text="@{bean.happenTime}"
                        android:layout_alignParentEnd="true"
                        android:layout_centerVertical="true"
                        tools:text="2023-05-16"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        app:layout_constraintEnd_toStartOf="@id/iv_fold"
                        android:layout_marginEnd="10dp"
                        />
                    <ImageView
                        android:id="@+id/iv_fold"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:background="@drawable/ic_fold"
                        app:layout_constraintTop_toTopOf="parent"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintEnd_toEndOf="parent"
                        android:layout_marginEnd="10dp"
                        />
                </androidx.constraintlayout.widget.ConstraintLayout>
                <LinearLayout
                    android:id="@+id/layout_content"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:paddingHorizontal="@dimen/dp_24"
                    >
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginBottom="6dp"
                        android:text="电子文件:"
                        android:textColor="@color/black"
                        android:textSize="12sp"
                        />
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal"
                        android:layout_marginBottom="15dp"
                        >
                        <androidx.recyclerview.widget.RecyclerView
                            android:id="@+id/rv_image"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            tools:listitem="@layout/item_electronic_file"
                            tools:itemCount="3"
                            />
                    </LinearLayout>
                    <LinearLayout
                        tools:visibility="visible"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:layout_marginBottom="12dp"
                        android:visibility="gone"
                        >
                        <LinearLayout
                            android:id="@+id/layout_modify"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            >
                            <ImageView
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:background="@drawable/ic_modify"
                                android:layout_gravity="center"
                                />
                            <TextView
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:text="修改"
                                android:textColor="@color/black"
                                android:textSize="@dimen/sp_14"
                                android:layout_marginStart="@dimen/dp_4"
                                />
                        </LinearLayout>
                        <LinearLayout
                            android:id="@+id/layout_delete"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginStart="@dimen/dp_52"
                            >
                            <ImageView
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:background="@drawable/ic_delete"
                                android:layout_gravity="center"
                                />
                            <TextView
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:text="删除"
                                android:textColor="#FFE86F72"
                                android:textSize="@dimen/sp_14"
                                android:layout_marginStart="@dimen/dp_4"
                                />
                        </LinearLayout>
                    </LinearLayout>
                </LinearLayout>
            </LinearLayout>
        </androidx.cardview.widget.CardView>
    </LinearLayout>
</layout>
app/src/main/res/layout/item_family_member.xml
@@ -1,9 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable
            name="bean"
            type="com.application.zhangshi_app_android.bean.HomeRootBean" />
    </data>
    <androidx.cardview.widget.CardView
@@ -17,7 +20,7 @@
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginHorizontal="12dp"
            android:layout_marginHorizontal="10dp"
            android:layout_marginVertical="5dp"
            android:orientation="horizontal"
            android:gravity="center"
@@ -28,9 +31,12 @@
                android:id="@+id/tv_generation"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="1"
                android:text="@{bean.identity+``}"
                android:textSize="18sp"
                android:textColor="#FFEBA4AA"
                android:gravity="center"
                android:maxLines="1"
                tools:text="100"
                />
            <!-- 头像 -->
@@ -42,13 +48,14 @@
                android:layout_marginEnd="10dp"
                android:scaleType="fitCenter"
                app:roundPercent="1"
                app:imageUrl="@{bean.img}"
                />
            <!-- 名字 -->
            <TextView
                android:id="@+id/tv_name"
                android:layout_width="70dp"
                android:layout_height="wrap_content"
                android:text="林佳林佳"
                android:text="@{bean.nickName}"
                android:textSize="16sp"
                android:textStyle="bold"
                android:textColor="#FFF6739F"
app/src/main/res/layout/item_tourism.xml
@@ -313,6 +313,7 @@
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:gravity="center_vertical"
                        android:layout_marginBottom="@dimen/dp_12"
                        android:layout_marginTop="6dp"
                        >
@@ -364,7 +365,7 @@
                            android:layout_height="wrap_content"
                            android:text="每日游记"
                            android:textColor="@color/black"
                            android:textSize="14sp"
                            android:textSize="18sp"
                            android:layout_marginStart="20dp"
                            />
                    </LinearLayout>
app/src/main/res/layout/layout_drawer.xml
@@ -27,7 +27,6 @@
                android:layout_width="50dp"
                android:layout_height="50dp"
                app:roundPercent="1"
                android:background="@drawable/img_sakura"
                />
            <TextView
                android:id="@+id/dl_home_user_name"
app/src/main/res/layout/pop_annual_health_status.xml
@@ -9,7 +9,7 @@
    app:cardElevation="0dp"
    >
    <LinearLayout
        android:layout_width="118dp"
        android:layout_width="85dp"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center"
@@ -25,20 +25,8 @@
            app:drawableStartCompat="@drawable/ic_modify"
            android:drawablePadding="5dp"
            />
        <View
            android:layout_width="match_parent"
            android:layout_height="0.3dp"
            android:background="#FF939393"
            />
        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/tv_annual_health_status"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:gravity="center"
            android:text="体检或看病"
            android:textColor="#FF333333"
            android:textSize="12sp"
            />
    </LinearLayout>
</androidx.cardview.widget.CardView>
app/src/main/res/layout/pop_basic_information_double.xml
@@ -5,6 +5,9 @@
    <data>
        <variable
            name="isFamily"
            type="boolean" />
        <variable
            name="spouseBean"
            type="com.application.zhangshi_app_android.bean.HomeRootBean" />
        <variable
@@ -190,7 +193,7 @@
                                    android:layout_width="wrap_content"
                                    android:layout_height="wrap_content"
                                    android:paddingHorizontal="6dp"
                                    android:text="@{`第`+ selfBean.identity + `代`}"
                                    android:text="@{`第`+ selfBean.identity + `代` + (isFamily?``:`配偶`)}"
                                    android:textColor="#FF000000"
                                    android:textSize="12sp"
                                    android:layout_gravity="center_vertical"
@@ -945,7 +948,7 @@
                                    android:paddingHorizontal="6dp"
                                    android:layout_gravity="center_vertical"
                                    app:textOverflowMode="@{4}"
                                    android:text="@{`第` + spouseBean.identity + `代`}"
                                    android:text="@{`第` + spouseBean.identity + `代`+ (isFamily?`配偶`:``)}"
                                    android:textColor="#FF000000"
                                    android:textSize="12sp"
                                    />
app/src/main/res/layout/pop_operate_exam_info.xml
New file
@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:cardBackgroundColor="#FFFAD1E0"
    app:cardCornerRadius="10dp"
    app:cardElevation="0dp"
    >
    <LinearLayout
        android:layout_width="118dp"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center_horizontal"
        >
        <LinearLayout
            android:id="@+id/layout_add"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:gravity="center_horizontal"
            >
            <TextView
                android:id="@+id/tv_add"
                android:layout_width="wrap_content"
                android:layout_height="32dp"
                android:gravity="center"
                android:text="新建"
                android:textColor="#FF333333"
                android:textSize="12sp"
                app:drawableStartCompat="@drawable/ic_operate_add"
                android:drawablePadding="5dp"
                />
            <View
                android:layout_width="match_parent"
                android:layout_height="0.3dp"
                android:background="#FF939393"
                />
        </LinearLayout>
        <LinearLayout
            android:id="@+id/layout_select"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:gravity="center_horizontal"
            >
            <TextView
                android:id="@+id/tv_select"
                android:layout_width="wrap_content"
                android:layout_height="32dp"
                android:text="选择"
                android:gravity="center"
                android:textColor="#FF333333"
                android:textSize="12sp"
                app:drawableStartCompat="@drawable/ic_operate_select"
                android:drawablePadding="5dp"
                />
            <View
                android:id="@+id/view_select_underline"
                android:layout_width="match_parent"
                android:layout_height="0.3dp"
                android:background="#FF939393"
                />
        </LinearLayout>
        <TextView
            android:id="@+id/tv_from_new_to_old"
            android:layout_width="wrap_content"
            android:layout_height="32dp"
            android:text="由新到旧"
            android:gravity="center"
            android:textColor="#FF333333"
            android:textSize="12sp"
            app:drawableStartCompat="@drawable/ic_operate_order"
            android:drawablePadding="3dp"
            />
        <View
            android:layout_width="match_parent"
            android:layout_height="0.3dp"
            android:background="#FF939393"
            />
        <TextView
            android:id="@+id/tv_from_old_to_new"
            android:layout_width="wrap_content"
            android:layout_height="32dp"
            android:text="由旧到新"
            android:gravity="center"
            android:textColor="#FF333333"
            android:textSize="12sp"
            app:drawableStartCompat="@drawable/ic_operate_order"
            android:drawablePadding="3dp"
            />
        <LinearLayout
            android:id="@+id/layout_exam_info"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:gravity="center_horizontal"
            >
            <View
                android:layout_width="match_parent"
                android:layout_height="0.3dp"
                android:background="#FF939393"
                />
            <TextView
                android:id="@+id/tv_exam_info"
                android:layout_width="wrap_content"
                android:layout_height="32dp"
                android:text="历年体检信息"
                android:gravity="center"
                android:textColor="#FF333333"
                android:textSize="12sp"
                android:drawablePadding="3dp"
                />
        </LinearLayout>
        <LinearLayout
            android:id="@+id/layout_health_care"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:gravity="center_horizontal"
            >
            <View
                android:layout_width="match_parent"
                android:layout_height="0.3dp"
                android:background="#FF939393"
                />
            <TextView
                android:id="@+id/tv_health_care"
                android:layout_width="wrap_content"
                android:layout_height="32dp"
                android:text="健康状况信息"
                android:gravity="center"
                android:textColor="#FF333333"
                android:textSize="12sp"
                android:drawablePadding="3dp"
                />
        </LinearLayout>
    </LinearLayout>
</androidx.cardview.widget.CardView>
app/src/main/res/values/strings.xml
@@ -1,5 +1,5 @@
<resources>
    <string name="app_name">张氏APP</string>
    <string name="app_name">本都都家网</string>
    <string name="title_home">首页</string>
    <string name="title_function">功能</string>
app_base/src/main/java/com/android/app_base/action/TitleBarAction.java
@@ -24,16 +24,16 @@
    /**
     * 设置标题栏的标题
     */
    default void setTitle(@StringRes int id) {
    default void setCenterTitle(@StringRes int id) {
        if (getTitleBar() != null) {
            setTitle(getTitleBar().getResources().getString(id));
            setCenterTitle(getTitleBar().getResources().getString(id));
        }
    }
    /**
     * 设置标题栏的标题
     */
    default void setTitle(CharSequence title) {
    default void setCenterTitle(CharSequence title) {
        if (getTitleBar() != null) {
            getTitleBar().setTitle(title);
        }
app_base/src/main/java/com/android/app_base/base/BaseConfig.java
@@ -6,7 +6,9 @@
 * @desc
 */
public class BaseConfig {
    public final static String BASE_URL = "http://47.93.189.255:8080";
    public final static String BASE_URL = "http://47.93.189.255:8080";// ip地址
    public final static String BASE_URL_DOMAIN = "https://www.bendudu.com:8080";//域名网址
    public final static int CODE_SUCCESS = 200;
    public static final int TOKEN_INVALID = 401;//token超时或失效
app_base/src/main/java/com/android/app_base/base/adapter/BaseVp2FragmentAdapter.java
@@ -171,6 +171,21 @@
    }
    /**
     * 获取某个 Fragment 的索引(没有就返回 -1)
     */
    public int getFragmentIndex(String clazz) {
        if (clazz == null) {
            return -1;
        }
        for (int i = 0; i < mFragmentList.size(); i++) {
            if (clazz.equals(mFragmentList.get(i).getClass().getName())) {
                return i;
            }
        }
        return -1;
    }
    /**
     * 根据 索引 获取某个 Fragment
     */
    public F getFragment(int index) {
app_base/src/main/java/com/android/app_base/base/adapter/databinding/ImageViewAdapter.java
@@ -28,11 +28,10 @@
        if (TextUtils.isEmpty(url)) {
            return;
        }
        if (url.contains("profile/upload")) {
            if (!url.contains("http")) {
                url = BaseConfig.BASE_URL + "/" + url;
            }
        if (url.contains("profile/upload")) {//如果是上传到服务器的图片
            //只取profile/upload以后的部分
            url = url.substring(url.indexOf("profile/upload"));
            url = BaseConfig.BASE_URL_DOMAIN + "/" + url;
        }
        GlideUtil.loadImage(url, imageView);
    }
app_base/src/main/java/com/android/app_base/base/adapter/databinding/TextViewAdapter.java
@@ -9,6 +9,7 @@
import androidx.databinding.InverseBindingAdapter;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Locale;
/**
@@ -68,7 +69,9 @@
//        if (!TextUtils.equals(view.getText().toString(), formattedValue)) {
//            view.setText(formattedValue);
//        }
        view.setText(BigDecimal.valueOf(value).stripTrailingZeros().toPlainString());
        //去掉小数点后面的0,保留两位小数
        view.setText(BigDecimal.valueOf(value).setScale(2, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString());
    }
    @InverseBindingAdapter(attribute = "android:text")
app_base/src/main/java/com/android/app_base/base/view/BaseActivity.java
@@ -187,6 +187,7 @@
     * 有需求的,在子类选择重写
     */
    protected void dialogLoading() {
    }
    protected void dialogDismiss() {
    }
app_base/src/main/java/com/android/app_base/base/viewmodel/BaseViewModel.java
@@ -77,7 +77,7 @@
     * 更改状态视图的状态
     */
    public void changeStateView(StateViewEnum state) {
        stateViewLiveData.setValue(state);
        stateViewLiveData.postValue(state);
    }
    @Override
app_base/src/main/java/com/android/app_base/http/OkHttpHelper.java
@@ -10,6 +10,7 @@
import com.android.app_base.http.interceptor.CacheInterceptor;
import com.android.app_base.http.interceptor.LogInterceptor;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.NetworkUtils;
import com.franmontiel.persistentcookiejar.PersistentCookieJar;
import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;
@@ -73,6 +74,16 @@
        });
        clientBuilder.addInterceptor(new LogInterceptor());//拦截器添加公共参数
        clientBuilder.addInterceptor(new AuthInterceptor());//拦截器token失效处理
        clientBuilder.addInterceptor(new Interceptor() {
            @NonNull
            @Override
            public Response intercept(@NonNull Chain chain) throws IOException {
                if (!NetworkUtils.isAvailable()) {
                    throw new IOException("当前网络不可用,请检查网络设置");
                }
                return chain.proceed(chain.request());
            }
        });
        //log日志拦截
        if (BuildConfig.DEBUG) {
            clientBuilder.addInterceptor(new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
app_base/src/main/java/com/android/app_base/http/interceptor/AuthInterceptor.java
@@ -25,7 +25,7 @@
/**
 * @author Ljj
 * @date 2023.04.07. 19:53
 * @desc
 * @desc 鉴权拦截器
 */
public class AuthInterceptor implements Interceptor {
app_base/src/main/java/com/android/app_base/widget/ExtendTitleBar.java
@@ -34,7 +34,6 @@
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//        System.out.println("onMeasure");
        reSetTitleGravity(titleGravity);
    }