Commit 1fc0e252 authored by 王雷's avatar 王雷

完善细节

parent 0b8f88d3
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
......@@ -7,7 +7,9 @@ plugins {
android {
compileSdkVersion 30
packagingOptions {
exclude 'META-INF/*.kotlin_module'
}
defaultConfig {
applicationId "com.qimai.yttgrass"
minSdkVersion 21
......@@ -27,6 +29,7 @@ android {
}
buildTypes {
release {
debuggable true
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
......@@ -69,7 +72,6 @@ dependencies {
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
api project(path: ':fetch')
implementation files('libs/tbs_sdk_thirdapp_v4.3.0.67_43967_sharewithdownloadwithfile_withoutGame_obfs_20200923_120452.jar')
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
......
......@@ -7,9 +7,9 @@
<application
android:name=".app.App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:icon="@drawable/ic_logo"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:roundIcon="@drawable/ic_logo"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/Theme.YttGrass">
......
package com.qimai.yttgrass
import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.Display
import android.view.View
import android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
import android.webkit.*
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.Navigation
import androidx.navigation.fragment.findNavController
import com.bumptech.glide.Glide
import com.qimai.android.fetch.Response.Status
import com.qimai.yttgrass.view.BaseFunc
import com.qimai.yttgrass.vm.HomeVm
import com.tencent.smtt.export.external.interfaces.WebResourceError
import com.tencent.smtt.export.external.interfaces.WebResourceRequest
import com.tencent.smtt.sdk.WebSettings
import com.tencent.smtt.sdk.WebView
import com.tencent.smtt.sdk.WebViewClient
import kotlinx.android.synthetic.main.fragment_goods_detail.*
import kotlinx.android.synthetic.main.fragment_welcome.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class DetailFragment(contentLayoutId: Int = R.layout.fragment_goods_detail) :
Fragment(contentLayoutId) {
private val TAG = "DetailFragment"
private val TAG = "DetailFragment"
private var mIsExpand = false
private var mCodeCurrentX = 0f
private var mOriginX = 0f
val mCutDownTime = 60
var mIndex = mCutDownTime
private lateinit var baseFunc:BaseFunc
private val mVm: HomeVm by lazy {
ViewModelProvider(requireActivity()).get(HomeVm::class.java)
}
@SuppressLint("SetJavaScriptEnabled")
private fun initJSExeLocaMethod() {
baseFunc = BaseFunc(requireActivity(), webview)
// --------html调用我们本地方法-----------
webview.addJavascriptInterface(baseFunc, "abc")
}
@SuppressLint("SetJavaScriptEnabled", "Recycle")
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
initJSExeLocaMethod()
view?.post {
mCodeCurrentX = getScreenWidth() - cl_mini_program_code.width - cl_mini_program_code.x
mOriginX = cl_mini_program_code.x
}
countdown()
addObserver()
mVm.mGoodsInfo?.apply {
webview.loadDataWithBaseURL(
null,
mVm.mGoodsInfo?.content?.let { getGoodsHtml(it) },
"text/html",
"UTF-8",
""
)
if (mVm.mGoodsInfo?.content.isNullOrEmpty()) {
ll_webview.visibility = View.GONE
} else {
ll_webview.visibility = View.VISIBLE
}
mVm.mGoodsInfo?.content?.let { getGoodsHtml(it) }?.let {
webview.loadDataWithBaseURL(
null,
it,
"text/html",
"UTF-8",
""
)
}
Glide.with(iv_introduction)
.load(this.showImg)
.into(iv_introduction)
tv_introduction.text = this.title
tv_sub_introduction.text = this.subTitle
}
if (!goodsId.isNullOrEmpty()) {
mVm.getMiniProgramCode(goodsId!!).observe(viewLifecycleOwner, Observer {
when (it.status) {
Status.SUCCESS -> {
Glide.with(iv_mini_program_img)
.load(it.data?.data?.code?.img)
.into(iv_mini_program_img)
}
Status.ERROR -> {
Log.d(TAG, "onActivityCreated: error= ${it.message}")
}
}
})
}
//把商品详情清理掉
mVm.mGoodsInfo = null
}
//设置不能滑动
......@@ -60,7 +107,8 @@ class DetailFragment(contentLayoutId: Int = R.layout.fragment_goods_detail) :
domStorageEnabled = true
blockNetworkImage = false
setAppCacheEnabled(false)
cacheMode = com.tencent.smtt.sdk.WebSettings.LOAD_NO_CACHE
setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN)
cacheMode =WebSettings.LOAD_NO_CACHE
loadsImagesAutomatically = true
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mixedContentMode = android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
......@@ -71,14 +119,15 @@ class DetailFragment(contentLayoutId: Int = R.layout.fragment_goods_detail) :
webview.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
view?.visibility = View.VISIBLE
// view?.visibility = View.VISIBLE
Log.d(TAG, "onPageStarted: ")
}
override fun onPageFinished(p0: WebView?, p1: String?) {
super.onPageFinished(p0, p1)
Log.d(TAG, "onPageFinished: ")
// imgReset()
imgReset()
webview.loadUrl("javascript:abc.resize(document.body.getBoundingClientRect().height)")
}
override fun onReceivedError(
......@@ -97,29 +146,111 @@ class DetailFragment(contentLayoutId: Int = R.layout.fragment_goods_detail) :
override fun shouldOverrideUrlLoading(p0: WebView?, p1: String?): Boolean {
Log.d(TAG, "shouldOverrideUrlLoading: url= $p1")
p0?.loadUrl(p1)
if (p1 != null) {
p0?.loadUrl(p1)
}
return true
}
}
// webview.loadUrl("https://www.qmai.cn/")
// webview.loadUrl("https://www.qmai.cn/")
iv_back.setOnClickListener {
Navigation.findNavController(it)
.navigateUp()
}
cl_mini_program_code.setOnClickListener {
val scaleAnination: ValueAnimator
if (!mIsExpand) {
scaleAnination = ValueAnimator.ofFloat(1f, 0.33f)
} else {
scaleAnination = ValueAnimator.ofFloat(0.33f, 1f)
}
mIsExpand = !mIsExpand
val animationSet = AnimatorSet()
animationSet.play(scaleAnination)
scaleAnination.addUpdateListener {
val value: Float = it.animatedValue as Float
cl_mini_program_code.scaleX = value
cl_mini_program_code.scaleY = value
Log.d(TAG, "onActivityCreated: value= $value")
/* if (value == 1f) {
cl_mini_program_code.x =
(getScreenWidth() - mCodeCurrentX - cl_mini_program_code.width*0.6).toFloat()
}else if (value==0.33f){
cl_mini_program_code.x = mOriginX
}*/
/* scaleAnination.addListener(object : Animator.AnimatorListener {
override fun onAnimationStart(p0: Animator?) {
}
override fun onAnimationEnd(p0: Animator?) {
}
override fun onAnimationCancel(p0: Animator?) {
}
override fun onAnimationRepeat(p0: Animator?) {
}
})*/
}
animationSet.duration = 500
animationSet.start()
}
}
private fun addObserver() {
mVm.mClickMutator.observe(viewLifecycleOwner, Observer {
if (it) {
mVm.mClickMutator.value = false
mIndex = mCutDownTime
}
})
}
private fun imgReset() {
webview.loadUrl("javascript:(function(){" +
"var objs = document.getElementsByTagName('img'); " +
"for(var i=0;i<objs.length;i++) " +
"{"
+ "var img = objs[i]; " +
" img.style.maxWidth = '100%';img.style.height='auto';" +
"}" +
"})()")
webview.loadUrl(
"javascript:(function(){" +
"var objs = document.getElementsByTagName('img'); " +
"for(var i=0;i<objs.length;i++) " +
"{"
+ "var img = objs[i]; " +
" img.style.maxWidth = '100%';img.style.height='auto';" +
"}" +
"})()"
)
}
private fun getGoodsHtml(content:String):String{
private fun getGoodsHtml(content: String): String {
return "<html> <body>${content}</body></html>"
}
private fun countdown() {
lifecycleScope.launch(Dispatchers.IO) {
while (mIndex != 0) {
delay(1000)
mIndex--
//倒计时结束返回上一页面
if (mIndex == 0) {
//mBackMutableLiveData.postValue(true)
withContext(Dispatchers.Main) {
view?.let {
Navigation.findNavController(it)
.navigateUp()
}
}
}
}
}
}
private fun getScreenWidth(): Float {
val display: Display = requireActivity().getWindowManager().defaultDisplay
return display.getWidth().toFloat()
}
}
\ No newline at end of file
......@@ -3,7 +3,9 @@ package com.qimai.yttgrass
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
......@@ -85,4 +87,10 @@ class MainActivity : AppCompatActivity() {
override fun onSupportNavigateUp(): Boolean {
return findNavController(this, R.id.nav_graph).navigateUp()
}
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
Log.d("activity", "dispatchTouchEvent: ")
mVm.mClickMutator.value = true
return super.dispatchTouchEvent(ev)
}
}
\ No newline at end of file
......@@ -23,50 +23,36 @@ class WelcomeFragment(contentLayoutId: Int = R.layout.fragment_welcome) :
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val datas = ArrayList<Int>()
datas.add(R.drawable.one)
datas.add(R.drawable.two)
datas.add(R.drawable.three)
datas.add(R.drawable.four)
datas.add(R.drawable.five)
addObserver()
mVm.getBannerUrl().observe(requireActivity(), Observer {
when (it.status) {
Status.SUCCESS -> {
banner.addBannerLifecycleObserver(this)
.setLoopTime(10000)
.adapter = ImageAdapter(it.data?.data?.images)
mVm.mBannerList.value = it.data?.data?.images
}
}
})
}
banner.postDelayed({
//mVm.mCodeMutableList.value = "1111"
},5000)
/* banner.setAdapter(BannerImageAdapter<Integer>(null) {
@Override
public void onBindView(BannerImageHolder holder, Integer data, int position, int size) {
//图片加载自己实现
Glide.with(holder.itemView)
.load(data.imageUrl)
.apply(RequestOptions.bitmapTransform(new RoundedCorners(30)))
.into(holder.imageView);
}
})*/
// .addBannerLifecycleObserver(this)//添加生命周期观察者
//.setIndicator(new CircleIndicator(this));
//更多使用方法仔细阅读文档,或者查看demo
addObserver()
private fun updateBanner(datas: ArrayList<String>) {
banner.addBannerLifecycleObserver(this)
.setLoopTime(10000)
.adapter = ImageAdapter(datas).apply {
setOff
}
}
private fun addObserver() {
mVm.mBannerList.observe(viewLifecycleOwner, Observer {
updateBanner(it)
})
mVm.mCodeMutableList.observe(viewLifecycleOwner, Observer<String> {
if (!it.isNullOrEmpty()) {
// Toast.makeText(requireActivity(), it, Toast.LENGTH_LONG).show()
// Log.d("value", "addObserver: value = $it")
// Toast.makeText(requireActivity(), it, Toast.LENGTH_LONG).show()
// Log.d("value", "addObserver: value = $it")
val newValue = it
mVm.mCodeMutableList.value = ""
mVm.getGoodsInfo("P5D6DDCCE9C3C03166", "0", "10783")
mVm.getGoodsInfo(newValue, "0", "44764")
.observe(requireActivity(), Observer {
when (it.status) {
Status.SUCCESS -> {
......@@ -74,7 +60,8 @@ class WelcomeFragment(contentLayoutId: Int = R.layout.fragment_welcome) :
it.data?.data?.img,
it.data?.data?.name,
it.data?.data?.goods?.content?.subheading,
it.data?.data?.goods?.content?.content
it.data?.data?.goods?.content?.content,
it.data?.data?.goods_id
)
mVm.mGoodsInfo = goods
Navigation.findNavController(banner)
......
......@@ -3,6 +3,7 @@ package com.qimai.yttgrass.api
import com.qimai.android.fetch.model.BaseData
import com.qimai.yttgrass.model.BannerInfoBean
import com.qimai.yttgrass.model.GoodsDetailBean
import com.qimai.yttgrass.model.MiniProgramInfoBean
import retrofit2.http.*
interface HomeService {
......@@ -18,4 +19,9 @@ interface HomeService {
@Field("store_multistores_id") store_multistores_id: String,
@Field("store_id") store_id: String
): BaseData<GoodsDetailBean>
@GET("web/retamarketing/no-state/ytt-qr-code")
suspend fun getMiniProgramCode(@Query("goods_id") goods_id: String): BaseData<MiniProgramInfoBean>
}
\ No newline at end of file
......@@ -3,30 +3,12 @@ package com.qimai.yttgrass.app
import android.app.Application
import android.util.Log
import com.qimai.android.widgetlib.toast.HolderContext
import com.tencent.smtt.sdk.QbSdk
import com.tencent.smtt.sdk.QbSdk.PreInitCallback
class App : Application() {
override fun onCreate() {
super.onCreate()
//搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
//搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
val cb: PreInitCallback = object : PreInitCallback {
override fun onViewInitFinished(arg0: Boolean) {
//x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
Log.d("app", " onViewInitFinished is $arg0")
}
override fun onCoreInitFinished() {
}
}
//x5内核初始化接口
//x5内核初始化接口
QbSdk.initX5Environment(applicationContext, cb)
HolderContext.getInstance().register { this }
}
......
package com.qimai.yttgrass.model
data class Code(
val img: String?,
val mini_path: String?
)
\ No newline at end of file
package com.qimai.yttgrass.model
class GoodsDetailBean (var name:String?,var img:String?,var goods:Goods){
class GoodsDetailBean (var name:String?,var img:String?,var goods:Goods?,var goods_id:String?){
}
class Goods(var content:Content)
......
package com.qimai.yttgrass.model
data class MiniProgramInfoBean(
val code: Code?
)
\ No newline at end of file
......@@ -4,5 +4,6 @@ class goodsInfoBean(
var showImg: String?,
var title: String?,
var subTitle: String?,
var content: String? = null
var content: String? = null,
var goodsId: String? = null
)
\ No newline at end of file
package com.qimai.yttgrass.view;
import android.app.Activity;
import android.view.ViewGroup;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.widget.LinearLayout;
public class BaseFunc {
Activity mActivity;
WebView webView;
public BaseFunc(Activity mActivity, WebView webView) {
this.mActivity = mActivity;
this.webView = webView;
}
//注册一个重新计算高度的方法
@JavascriptInterface
public void resize(final float height) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
webView.setLayoutParams(new LinearLayout.LayoutParams(mActivity.getResources().getDisplayMetrics().widthPixels, (int) (height * mActivity.getResources().getDisplayMetrics().density)+20));
webView.requestLayout();
webView.invalidate();
}
});
}
}
......@@ -2,20 +2,31 @@ package com.qimai.yttgrass.vm
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.qimai.android.fetch.Fetch
import com.qimai.android.fetch.FetchWebApi
import com.qimai.android.fetch.extention.safeCall
import com.qimai.yttgrass.api.HomeService
import com.qimai.yttgrass.model.SingleLiveEvent
import com.qimai.yttgrass.model.goodsInfoBean
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import retrofit2.http.Field
import retrofit2.http.Query
class HomeVm : ViewModel() {
val mCodeMutableList: SingleLiveEvent<String> by lazy {
SingleLiveEvent<String>()
}
private var mPause = false
val mBannerList = MutableLiveData<ArrayList<String>>()
var mBackMutableLiveData: MutableLiveData<Boolean> = MutableLiveData<Boolean>()
var mClick = false
var mClickMutator: MutableLiveData<Boolean> = MutableLiveData<Boolean>()
//商品详情
var mGoodsInfo:goodsInfoBean?=null
var mGoodsInfo: goodsInfoBean? = null
val webapi = FetchWebApi.instance.createApi(HomeService::class.java)
fun getBannerUrl() = safeCall {
......@@ -29,4 +40,26 @@ class HomeVm : ViewModel() {
) = safeCall {
webapi.getGoodsInfo(product_no, store_multistores_id, store_id)
}
fun getMiniProgramCode(goods_id: String) = safeCall {
webapi.getMiniProgramCode(goods_id)
}
fun countdown() {
var index = 0
viewModelScope.launch(Dispatchers.IO) {
while (true) {
if (mClick){
index = 0
}
delay(1000)
index++
if (index == 60) {
mBackMutableLiveData.postValue(true)
}
}
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f5f5f5"
xmlns:tools="http://schemas.android.com/tools">
android:background="#f5f5f5">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_toolbar"
......@@ -39,13 +39,14 @@
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:fillViewport="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_toolbar">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_introduction"
......@@ -56,67 +57,110 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/ll_tips"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:paddingBottom="17dp"
android:orientation="vertical"
android:paddingTop="18.5dp"
app:layout_constraintTop_toBottomOf="@id/iv_introduction"
android:paddingBottom="17dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
app:layout_constraintTop_toBottomOf="@id/iv_introduction">
<TextView
android:id="@+id/tv_introduction"
app:layout_constraintTop_toBottomOf="@id/iv_introduction"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingExtra="2dp"
android:text="洽洽香瓜子焦糖核桃味香瓜子焦糖核桃味芝麻绿豆香瓜子焦糖核桃味香瓜子焦糖核桃味芝麻绿豆香"
android:textColor="#ff333333"
android:textSize="20sp"
/>
<TextView
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_introduction"
android:id="@+id/tv_sub_introduction"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="满满一口焦糖香加核桃催满足你的味蕾"
android:textColor="#ff666666"
android:textSize="15sp"
/>
<TextView
android:id="@+id/tv_introduction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:lineSpacingExtra="2dp"
android:text="洽洽香瓜子焦糖核桃味香瓜子焦糖核桃味芝麻绿豆香瓜子焦糖核桃味香瓜子焦糖核桃味芝麻绿豆香"
android:textColor="#ff333333"
android:textSize="20sp"
app:layout_constraintTop_toBottomOf="@id/iv_introduction" />
<TextView
android:id="@+id/tv_sub_introduction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginRight="16dp"
android:text="满满一口焦糖香加核桃催满足你的味蕾"
android:textColor="#ff666666"
android:textSize="15sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_introduction" />
</LinearLayout>
<LinearLayout
android:layout_marginTop="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll_tips"
android:id="@+id/ll_webview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical"
>
<com.tencent.smtt.sdk.WebView
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll_tips">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:visibility="visible"
tools:ignore="WebViewLayout" />
<Space
android:layout_width="match_parent"
android:layout_height="20dp"/>
android:layout_height="20dp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_mini_program_code"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginRight="30dp"
android:layout_marginBottom="30dp"
android:background="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintWidth_percent="0.25">
<ImageView
android:id="@+id/iv_mini_program_img"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="13dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<RelativeLayout
android:id="@+id/rl_change"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.2">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:src="@drawable/excahnge_icon" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment