作者 杨谦

1.部分样式调整

2.视频跳转修改等
... ... @@ -9,6 +9,7 @@ package com.br_technology.securitytrain_master.base.common
object ConstantParamKey {
// 视频/线下培训课节id
const val COURSE_BEAN = "course_bean"
const val COURSE_LESSON = "course_lesson"
// 课程描述
const val COURSE_DES = "course_des"
... ...
package com.br_technology.securitytrain_master.expand;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import androidx.annotation.ColorRes;
import java.util.Collection;
/**
* 像素,dp.px互转
*/
public class TranslateUnit {
private static WindowManager windowManager;
private static WindowManager getWindowManager(Context context) {
if (windowManager == null) {
windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
}
return windowManager;
}
public static float getDensity(Context context) {
return context.getResources().getDisplayMetrics().density;
}
public static float getFontDensity(Context context) {
return context.getResources().getDisplayMetrics().scaledDensity;
}
public static DisplayMetrics getDisplayMetrics(Context context) {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager(context).getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics;
}
public static int dp2px(Context context, float dp) {
return (int) (getDensity(context) * dp + 0.5f);
}
public static int px2dp(Context context, float px) {
return (int) (px / getDensity(context) + 0.5f);
}
public static int sp2px(Context context, float sp) {
return (int) (getFontDensity(context) * sp + 0.5f);
}
public static int px2sp(Context context, float px) {
return (int) (px / getFontDensity(context) + 0.5f);
}
public static int getWindowWidth(Context context) {
return getDisplayMetrics(context).widthPixels;
}
public static int getWindowHeight(Context context) {
return getDisplayMetrics(context).heightPixels;
}
public static String getPathFormat(String path) {
if (!TextUtils.isEmpty(path)) {
int lastPeriodIndex = path.lastIndexOf('.');
if (lastPeriodIndex > 0 && lastPeriodIndex + 1 < path.length()) {
String format = path.substring(lastPeriodIndex + 1);
if (!TextUtils.isEmpty(format)) {
return format.toLowerCase();
}
}
}
return "";
}
public static boolean isGif(String url) {
return "gif".equals(getPathFormat(url));
}
public static Bitmap getTextBitmap(Context context, int width, int height, int radius, String text, int textSize, @ColorRes int bgColor) {
radius = dp2px(context, radius);
Bitmap bitmap = Bitmap.createBitmap(dp2px(context, width), dp2px(context, height), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
RectF rect = new RectF(0, 0, canvas.getWidth(), canvas.getHeight());
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(context.getResources().getColor(bgColor));
canvas.drawRoundRect(new RectF(0, 0, rect.width(), rect.height()), radius, radius, paint);
paint.setColor(Color.WHITE);
paint.setTextSize(dp2px(context, textSize));
paint.setTextAlign(Paint.Align.CENTER);
Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();
float baseline = (rect.bottom + rect.top - fontMetrics.bottom - fontMetrics.top) / 2;
canvas.drawText(text, rect.centerX(), baseline, paint);
return bitmap;
}
public static Drawable getTextDrawable(Context context, int width, int height, int radius, String text, int textSize, @ColorRes int bgColor) {
return new BitmapDrawable(getTextBitmap(context, width, height, radius, text, textSize, bgColor));
}
public static boolean isEmpty(Collection<?> collection) {
return collection == null || collection.isEmpty();
}
public static int getSize(Collection<?> collection) {
return collection == null ? 0 : collection.size();
}
}
... ...
... ... @@ -119,7 +119,7 @@ open class TrainCourseDetailItem(var type: Int) : MultiItemEntity {
var lessonVideo: LessonClazz? = null
var lessonVideoNormal: LessonClassDetail? = null
var lessonLive: LessonLive? = null
var lessonOff: LessonOfflineClazz? = null
var lessonOff: LessonOfflineDetail? = null
override val itemType: Int
get() = type
... ...
... ... @@ -40,12 +40,13 @@ class OnlineActivity :
val data = videoLessonList!![position]
course.mLessonId = "${data.id}"
course.isTrainClass = false
course.type = data.type.toInt()
course.type = 1
startActivity(
Intent(
this@OnlineActivity,
CourseDetailActivity::class.java
).putExtra(ConstantParamKey.COURSE_BEAN, course)
.putExtra(ConstantParamKey.COURSE_LESSON, data)
)
}
initLoadMore()
... ...
... ... @@ -9,6 +9,7 @@ import com.br_technology.securitytrain_master.ui.bean.TrainCourseDetailItemType.
import com.br_technology.securitytrain_master.ui.bean.TrainCourseDetailItemType.TYPE_COURSE_DETAIL_ITEM_NORMAL
import com.br_technology.securitytrain_master.ui.bean.TrainCourseDetailItemType.TYPE_COURSE_DETAIL_ITEM_OFF
import com.br_technology.securitytrain_master.ui.bean.TrainCourseDetailItemType.TYPE_COURSE_DETAIL_ITEM_VIDEO
import com.br_technology.securitytrain_master.ui.view.home.bean.VideoLessonBean
import com.br_technology.securitytrain_master.ui.view.home.bean.WorkTypeBean
import com.br_technology.securitytrain_master.ui.view.home.fragment.CourseListFragment
import com.br_technology.securitytrain_master.ui.view.home.fragment.OnlineDetailFragment
... ... @@ -28,6 +29,7 @@ class CourseDetailActivity
) {
private var searchResultAdapter: BasePagerAdapter? = null
private var courseBean: CourseParam? = null
private var courseLesson: VideoLessonBean.ListBean.DataBean? = null
private var mWorkBean: WorkTypeBean? = null
private var mapWork = mutableMapOf<Int, WorkTypeBean.ListBean>()
... ... @@ -48,11 +50,11 @@ class CourseDetailActivity
it.data.detail.name,
setPosName(posIds),
it.data.detail.content
)
), TYPE_COURSE_DETAIL_ITEM_VIDEO
),
CourseListFragment(TrainCourseData(TYPE_COURSE_DETAIL_ITEM_VIDEO).apply {
this.lessonBean = it.data
},"${courseBean?.mTrainClassId}")
}, "${courseBean?.mTrainClassId}")
)
val titles = listOf("课程详情", "课程列表")
searchResultAdapter?.addData(list.toMutableList())
... ... @@ -64,17 +66,22 @@ class CourseDetailActivity
mViewModel.mVideoLessonNormal.observe(this, {
binding.apply {
Glide.with(this@CourseDetailActivity).load(it.data.detail.video).into(ivTop)
searchResultAdapter = BasePagerAdapter(
supportFragmentManager,
FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
)
val list =
mutableListOf(
OnlineDetailFragment(TrainClassDes(it.data.detail.name, "", "")),
OnlineDetailFragment(
TrainClassDes(
courseLesson?.name ?: "",
courseLesson?.pos_ids ?: "",
courseLesson?.content ?: ""
), TYPE_COURSE_DETAIL_ITEM_NORMAL
),
CourseListFragment(TrainCourseData(TYPE_COURSE_DETAIL_ITEM_NORMAL).apply {
this.lessonBeanNormal = it.data.detail
},"${courseBean?.mTrainClassId}")
}, "${courseBean?.mTrainClassId}")
)
val titles = listOf("课程详情", "课程列表")
searchResultAdapter?.addData(list.toMutableList())
... ... @@ -93,10 +100,13 @@ class CourseDetailActivity
)
val list =
mutableListOf(
OnlineDetailFragment(TrainClassDes(it.data.detail.name, "", "")),
OnlineDetailFragment(
TrainClassDes(it.data.detail.name, "", ""),
TYPE_COURSE_DETAIL_ITEM_LIVE
),
CourseListFragment(TrainCourseData(TYPE_COURSE_DETAIL_ITEM_LIVE).apply {
this.lessonLive = it.data.detail
},"${courseBean?.mTrainClassId}")
}, "${courseBean?.mTrainClassId}")
)
val titles = listOf("课程详情", "课程列表")
searchResultAdapter?.addData(list.toMutableList())
... ... @@ -121,11 +131,11 @@ class CourseDetailActivity
it.data.detail.name,
setPosName(posIds),
it.data.detail.content
)
), TYPE_COURSE_DETAIL_ITEM_OFF
),
CourseListFragment(TrainCourseData(TYPE_COURSE_DETAIL_ITEM_OFF).apply {
this.lessonOff = it.data.detail
},"${courseBean?.mTrainClassId}")
}, "${courseBean?.mTrainClassId}")
)
val titles = listOf("课程详情", "课程列表")
searchResultAdapter?.addData(list.toMutableList())
... ... @@ -151,6 +161,10 @@ class CourseDetailActivity
override fun initData() {
super.initData()
courseBean = intent.getParcelableExtra(ConstantParamKey.COURSE_BEAN)
courseLesson = intent.getParcelableExtra(ConstantParamKey.COURSE_LESSON)
courseLesson?.let {
Glide.with(this@CourseDetailActivity).load(it.image).into(binding.ivTop)
}
mViewModel.workType()
mViewModel.mWorkBean.observe(this, {
mWorkBean = it.data
... ...
... ... @@ -115,13 +115,15 @@ fun transData(data: TrainCourseDetailItem, pos: Int): List<TrainCourseDetailItem
}
}
TYPE_COURSE_DETAIL_ITEM_OFF -> {
data.lessonOff?.apply {
data.lessonOff?.let {
for (p in it.lessonofflineclass) {
list.add(TrainCourseDetailItemChild(TYPE_COURSE_DETAIL_ITEM_OFF, pos).apply {
lessonOffChild = data.lessonOff
lessonOffChild = p
})
}
}
}
}
return list
}
... ...
package com.br_technology.securitytrain_master.ui.view.home.bean;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.List;
/**
... ... @@ -65,7 +68,7 @@ public class VideoLessonBean {
this.data = data;
}
public static class DataBean {
public static class DataBean implements Parcelable {
private Integer id;
private String type;
private Integer company_id;
... ... @@ -276,6 +279,90 @@ public class VideoLessonBean {
this.avatar = avatar;
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(this.id);
dest.writeString(this.type);
dest.writeValue(this.company_id);
dest.writeString(this.name);
dest.writeString(this.des);
dest.writeString(this.image);
dest.writeString(this.pos_ids);
dest.writeValue(this.teacher_id);
dest.writeValue(this.class_hours);
dest.writeValue(this.score);
dest.writeString(this.is_open);
dest.writeString(this.is_rec);
dest.writeString(this.content);
dest.writeString(this.class_json);
dest.writeValue(this.create_time);
dest.writeValue(this.update_time);
dest.writeString(this.pos_name);
dest.writeString(this.create_time_text);
}
public void readFromParcel(Parcel source) {
this.id = (Integer) source.readValue(Integer.class.getClassLoader());
this.type = source.readString();
this.company_id = (Integer) source.readValue(Integer.class.getClassLoader());
this.name = source.readString();
this.des = source.readString();
this.image = source.readString();
this.pos_ids = source.readString();
this.teacher_id = (Integer) source.readValue(Integer.class.getClassLoader());
this.class_hours = (Integer) source.readValue(Integer.class.getClassLoader());
this.score = (Integer) source.readValue(Integer.class.getClassLoader());
this.is_open = source.readString();
this.is_rec = source.readString();
this.content = source.readString();
this.class_json = source.readString();
this.create_time = (Integer) source.readValue(Integer.class.getClassLoader());
this.update_time = (Integer) source.readValue(Integer.class.getClassLoader());
this.pos_name = source.readString();
this.create_time_text = source.readString();
}
public DataBean() {
}
protected DataBean(Parcel in) {
this.id = (Integer) in.readValue(Integer.class.getClassLoader());
this.type = in.readString();
this.company_id = (Integer) in.readValue(Integer.class.getClassLoader());
this.name = in.readString();
this.des = in.readString();
this.image = in.readString();
this.pos_ids = in.readString();
this.teacher_id = (Integer) in.readValue(Integer.class.getClassLoader());
this.class_hours = (Integer) in.readValue(Integer.class.getClassLoader());
this.score = (Integer) in.readValue(Integer.class.getClassLoader());
this.is_open = in.readString();
this.is_rec = in.readString();
this.content = in.readString();
this.class_json = in.readString();
this.create_time = (Integer) in.readValue(Integer.class.getClassLoader());
this.update_time = (Integer) in.readValue(Integer.class.getClassLoader());
this.pos_name = in.readString();
this.create_time_text = in.readString();
}
public static final Creator<DataBean> CREATOR = new Creator<DataBean>() {
@Override
public DataBean createFromParcel(Parcel source) {
return new DataBean(source);
}
@Override
public DataBean[] newArray(int size) {
return new DataBean[size];
}
};
}
}
}
... ...
... ... @@ -58,15 +58,13 @@ class CourseListFragment(var courseData: TrainCourseData,var tranClassId:String)
})
}
TYPE_COURSE_DETAIL_ITEM_OFF -> {
courseData.lessonOff?.apply {
for (p in lessonofflineclass) {
courseData.lessonOff?.let {
dataList.add(TrainCourseDetailItem(TYPE_COURSE_DETAIL_ITEM_OFF).apply {
lessonOff = p
lessonOff = it
})
}
}
}
}
binding.recyclerview.adapter = CourseDetailListAdapter().apply {
addData(dataList)
setListener(object : IItemClick {
... ...
... ... @@ -21,7 +21,7 @@ import com.br_technology.securitytrain_master.ui.view.home.bean.NoticeBean
import com.br_technology.securitytrain_master.ui.view.home.bean.RecommendBean
import com.br_technology.securitytrain_master.ui.view.home.bean.VideoLessonBean
import com.br_technology.securitytrain_master.ui.view.home.viewmodel.HomeViewModel
import com.br_technology.securitytrain_master.view.DialogNotice
import com.br_technology.securitytrain_master.view.DialogTips
import com.br_technology.securitytrain_master.view.listener.OnItemClickListener
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
... ... @@ -50,8 +50,9 @@ class HomeFragment :
private var videoCourseAdapter: VideoCourseAdapter? = null
private val dialogNotice by lazy {
DialogNotice(requireContext())
DialogTips(requireContext())
}
override fun initDataObserver() {
//获取banner数据
mViewModel.mBannerBean.observe(this, {
... ... @@ -71,7 +72,23 @@ class HomeFragment :
textView.setOnClickListener {
val position = textView.tag as Int
// 公告弹框
dialogNotice.setTitle(data[position].des).show()
dialogNotice.setData(data[position].title, data[position].des).show()
}
binding.flipperScan.addView(
textView, ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
)
}
for (news in data) {
val textView = TextView(context)
textView.maxLines = 1
textView.text = news.title
textView.ellipsize = TextUtils.TruncateAt.END
textView.setOnClickListener {
// 公告弹框
ToastUtils.s(requireContext(), "aaa")
}
binding.flipperScan.addView(
textView, ViewGroup.LayoutParams(
... ... @@ -80,22 +97,6 @@ class HomeFragment :
)
)
}
// for (news in data) {
// val textView = TextView(context)
// textView.maxLines = 1
// textView.text = news.title
// textView.ellipsize = TextUtils.TruncateAt.END
// textView.setOnClickListener {
// // 公告弹框
// ToastUtils.s(requireContext(),"aaa")
// }
// binding.flipperScan.addView(
// textView, ViewGroup.LayoutParams(
// ViewGroup.LayoutParams.MATCH_PARENT,
// ViewGroup.LayoutParams.WRAP_CONTENT
// )
// )
// }
if (data.size > 1) {
binding.flipperScan.flipInterval = 3000
binding.flipperScan.startFlipping()
... ... @@ -223,13 +224,14 @@ class HomeFragment :
val data = videoLessonList!![position]
course.mLessonId = "${data.id}"
course.isTrainClass = false
course.type = data.type.toInt()
course.type = 1
//视频详情
startActivity(
Intent(
requireContext(),
CourseDetailActivity::class.java
).putExtra(ConstantParamKey.COURSE_BEAN, course)
.putExtra(ConstantParamKey.COURSE_LESSON, data)
)
}
recommendDataAdapter = RecommendDataAdapter()
... ...
package com.br_technology.securitytrain_master.ui.view.home.fragment
import android.view.View
import com.br_technology.securitytrain_master.databinding.FragmentOnlineDetailBinding
import com.br_technology.securitytrain_master.ui.bean.TrainClassDes
import com.br_technology.securitytrain_master.ui.bean.TrainCourseDetailItemType
import com.br_technology.securitytrain_master.ui.view.home.viewmodel.OnlineDetailFragmentViewModel
import com.wjx.android.wanandroidmvvm.base.view.BaseLifeCycleFragment
... ... @@ -10,7 +12,7 @@ import com.wjx.android.wanandroidmvvm.base.view.BaseLifeCycleFragment
* Author: Captain
* Description: 初见时你很迷人
*/
class OnlineDetailFragment(val data: TrainClassDes) :
class OnlineDetailFragment(val data: TrainClassDes, var type: Int) :
BaseLifeCycleFragment<OnlineDetailFragmentViewModel, FragmentOnlineDetailBinding>(
FragmentOnlineDetailBinding::inflate
) {
... ... @@ -19,6 +21,9 @@ class OnlineDetailFragment(val data: TrainClassDes) :
override fun initData() {
super.initData()
if (TrainCourseDetailItemType.TYPE_COURSE_DETAIL_ITEM_NORMAL == type) {
binding.llContent.visibility = View.GONE
}
binding.tvPos.text = data.pos
binding.title.text = data.title
binding.webView.loadData(data.content)
... ...
package com.br_technology.securitytrain_master.view
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import com.br_technology.securitytrain_master.R
import com.br_technology.securitytrain_master.databinding.DialogTipsBinding
import com.br_technology.securitytrain_master.expand.dp2px
import com.br_technology.securitytrain_master.expand.screenWidth
/**
* Author by YSir
* Date on 2022/1/25.
* description
* PS: Not easy to write code, please indicate.
*/
class DialogTips(context: Context) : Dialog(context, R.style.UserDefaultDialog) {
private val binding by lazy {
DialogTipsBinding.inflate(LayoutInflater.from(context))
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
val attributes = window?.attributes
attributes?.width = binding.root.screenWidth() - 80.dp2px()
// 点击区域外取消
setCanceledOnTouchOutside(false)
setCancelable(true)
binding.apply {
// 确定
tvEnsure.setOnClickListener {
dismiss()
}
}
}
fun setData(title: String, content: String): DialogTips {
binding.tvTitle.text = title
binding.tvMention.loadData(content)
return this
}
}
\ No newline at end of file
... ...
... ... @@ -2,8 +2,10 @@ package com.br_technology.securitytrain_master.view
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.webkit.WebSettings
import android.webkit.WebView
import com.br_technology.securitytrain_master.expand.dp2px
import com.br_technology.securitytrain_master.expand.TranslateUnit
import com.br_technology.securitytrain_master.util.HtmlConvert
import org.jsoup.Jsoup
... ... @@ -16,17 +18,20 @@ class MyWebView(context: Context, attrs: AttributeSet?) : WebView(context, attrs
init {
settings.javaScriptEnabled = true
settings.minimumFontSize = 14.dp2px()
settings.defaultFixedFontSize = 15.dp2px()
settings.minimumFontSize = TranslateUnit.sp2px(context, 14f)
settings.defaultFixedFontSize = TranslateUnit.sp2px(context, 15f)
settings.useWideViewPort = true
settings.loadWithOverviewMode = true
settings.allowFileAccess = true
settings.allowFileAccessFromFileURLs = true
settings.allowUniversalAccessFromFileURLs = true
settings.layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS
scrollBarStyle = View.SCROLLBARS_INSIDE_OVERLAY
isScrollContainer = false
isVerticalScrollBarEnabled = false
isHorizontalScrollBarEnabled = false
setBackgroundColor(0); // 设置背景色
}
... ...
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/solid_96_4"
android:backgroundTint="@color/white"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:gravity="center"
android:textStyle="bold"
android:padding="12dp"
android:textColor="@color/black"
android:textSize="20sp" />
<com.br_technology.securitytrain_master.view.MyWebView
android:id="@+id/tv_mention"
android:layout_marginStart="@dimen/dp_10"
android:layout_marginEnd="10dp"
android:layout_width="match_parent"
android:layout_height="220dp"/>
<TextView
android:id="@+id/tv_ensure"
android:layout_width="130dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="16dp"
android:gravity="center"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:layout_marginTop="10dp"
android:background="@drawable/solid_25_4"
android:paddingStart="30dp"
android:paddingEnd="30dp"
android:text="确认"
android:textColor="@color/white"
android:textSize="16sp" />
</LinearLayout>
</FrameLayout>
\ No newline at end of file
... ...
... ... @@ -7,16 +7,18 @@
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:paddingStart="16dp"
android:paddingEnd="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
... ... @@ -38,15 +40,16 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:orientation="horizontal"
android:paddingStart="16dp">
<TextView
android:id="@+id/tv_pos"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/shiyong"
... ... @@ -62,20 +65,15 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="16dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="16dp"
android:textColor="@color/color_32"
android:textSize="17sp"
tools:text="话费的回复是单号发大师傅但是感觉还是风格的" />
<com.br_technology.securitytrain_master.view.MyWebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp" />
android:layout_width="fill_parent"
android:layout_height="match_parent" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
\ No newline at end of file
... ...