Commit 4ae88a69 authored by wanglei's avatar wanglei

第一次提交

parent 43f8027a
Pipeline #1211 failed with stages
*.iml
.gradle
/local.properties
.idea
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
# Browser White # 浏览器内核
1.Android系统内置的WebView组件
2.ChromiumWebView:一个基于Chromium的Android WebView封装库
# 页卡堆栈效果
1.关键字:StackView不行太局限
2.[CardSlidePanel](https://github.com/xmuSistone/CardSlidePanel)
3.移动的关键类 ItemTouchHelper
4.使用LinkedList维护列表
5.遮罩效果PorterDuff.Mode.SRC_IN
6.getWindow().requestFeature(13);
7.postponeEnterTransition();
浏览器第一个包
\ No newline at end of file
/build
\ No newline at end of file
plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.jetbrainsKotlinAndroid)
}
android {
namespace = "com.base.browserwhite"
compileSdk = 34
defaultConfig {
applicationId = "com.base.browserwhite"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
viewBinding = true
buildConfig = true
}
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
package com.base.browserwhite
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.base.browserwhite", appContext.packageName)
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.BrowserWhite"
tools:targetApi="31">
<activity
android:name=".ui.activity.news.NewsActivity"
android:exported="false" />
<activity
android:name=".ui.activity.webbrowser.WebBrowserActivity"
android:exported="false" />
<activity
android:name=".ui.activity.labelstack.LabelStackActivity"
android:exported="false" />
<activity
android:name=".ui.activity.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
package com.base.browserwhite.bean
import android.graphics.Bitmap
class LabelBean(
var no:Int=0,
var elevation: Float = 0f,
var bitmap: Bitmap? = null,
) {
var isSelect: Boolean = false
}
\ No newline at end of file
package com.base.browserwhite.bean
import android.net.Uri
data class MediaBean(
val path: String = "",
val uri: Uri = Uri.EMPTY,
val size: Long = 0
)
package com.base.browserwhite.bean
import android.graphics.drawable.Drawable
import android.net.Uri
class WebSiteBean(
val name: String = "",
val icon: Int = 0,
val iconUri: Uri = Uri.EMPTY
) {
var increase = false
}
\ No newline at end of file
package com.base.browserwhite.ui.activity
import android.app.Dialog
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.base.browserwhite.utils.ActivityLauncher
import com.base.browserwhite.utils.ActivityManagerUtils
abstract class BaseActivity<T : ViewBinding> : AppCompatActivity() {
protected abstract val binding: T
lateinit var launcher: ActivityLauncher
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = ActivityLauncher(this)
setContentView(binding.root)
// EventUtils.event("page_${javaClass.simpleName}")
initView()
initListener()
}
protected abstract fun initView()
protected open fun initListener() {}
fun finishToMain() {
if (this !is MainActivity && !ActivityManagerUtils.getInstance().isActivityInStack(MainActivity::class.java)) {
startActivity(Intent(this, MainActivity::class.java))
}
finish()
}
var dialog: Dialog? = null
override fun onDestroy() {
super.onDestroy()
ActivityManagerUtils.getInstance().removeActivity(this)
if (dialog != null) {
dialog?.dismiss()
dialog = null
}
}
}
\ No newline at end of file
package com.base.browserwhite.ui.activity
import android.graphics.Color
import androidx.core.view.isEmpty
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import com.base.browserwhite.R
import com.base.browserwhite.databinding.ActivityMainBinding
import com.base.browserwhite.ui.fragment.FileFragment
import com.base.browserwhite.ui.fragment.HomeFragment
import com.base.browserwhite.utils.BarUtils
class MainActivity : BaseActivity<ActivityMainBinding>() {
private val homeFragment: HomeFragment by lazy {
HomeFragment()
}
private val fileFragment: FileFragment by lazy {
FileFragment()
}
override val binding: ActivityMainBinding by lazy {
ActivityMainBinding.inflate(layoutInflater)
}
override fun initView() {
BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
// startActivity(Intent(this, LabelStackActivity::class.java))
}
override fun initListener() {
super.initListener()
binding.llHome.setOnClickListener {
disSelect()
binding.llHome.isSelected = true
changeFragment(homeFragment)
}
binding.llFile.setOnClickListener {
disSelect()
binding.llFile.isSelected = true
changeFragment(fileFragment)
}
binding.llHome.callOnClick()
}
private fun changeFragment(fragment: Fragment) {
val transaction = supportFragmentManager.beginTransaction()
if (binding.fragmentContainer.isEmpty()) {
transaction.add(R.id.fragment_container, fragment)
} else {
transaction.replace(R.id.fragment_container, fragment)
}
transaction.commit()
}
private fun disSelect() {
binding.llHome.isSelected = false
binding.llFile.isSelected = false
}
}
\ No newline at end of file
package com.base.browserwhite.ui.activity.labelstack
import android.graphics.Color
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.base.browserwhite.R
import com.base.browserwhite.bean.LabelBean
import com.base.browserwhite.databinding.ItemLabelBinding
import com.base.browserwhite.utils.XmlEx.inflate
import kotlin.random.Random
class LabelAdapter : RecyclerView.Adapter<LabelAdapter.LabelViewHolder>() {
inner class LabelViewHolder(view: View) : ViewHolder(view)
private var beanList = arrayListOf(
LabelBean(),
LabelBean(),
LabelBean()
)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LabelViewHolder {
return LabelViewHolder(R.layout.item_label.inflate(parent))
}
override fun getItemCount(): Int {
return beanList.size
}
override fun onBindViewHolder(holder: LabelViewHolder, position: Int) {
val binding = ItemLabelBinding.bind(holder.itemView)
binding.root.setCardBackgroundColor(generateRandomColor())
}
fun generateRandomColor(): Int {
// 生成随机的 Alpha(透明度)、Red(红色)、Green(绿色)、Blue(蓝色)值
val alpha = Random.nextInt(255) // 透明度,从 0 到 255,然后右移24位,确保在 0xFF 范围内
val red = Random.nextInt(256)
val green = Random.nextInt(256)
val blue = Random.nextInt(256)
// 将ARGB值组合成一个颜色值
return Color.argb(alpha, red, green, blue)
}
}
\ No newline at end of file
package com.base.browserwhite.ui.activity.labelstack
import androidx.recyclerview.widget.LinearLayoutManager
import com.base.browserwhite.databinding.ActivityLabelStackBinding
import com.base.browserwhite.ui.activity.BaseActivity
class LabelStackActivity : BaseActivity<ActivityLabelStackBinding>() {
private lateinit var adapter: LabelAdapter
override val binding: ActivityLabelStackBinding by lazy {
ActivityLabelStackBinding.inflate(layoutInflater)
}
override fun initView() {
adapter = LabelAdapter()
binding.rv.adapter = adapter
}
}
\ No newline at end of file
package com.base.browserwhite.ui.activity.news
import com.base.browserwhite.databinding.ActivityNewsBinding
import com.base.browserwhite.ui.activity.BaseActivity
class NewsActivity : BaseActivity<ActivityNewsBinding>() {
override val binding: ActivityNewsBinding by lazy {
ActivityNewsBinding.inflate(layoutInflater)
}
override fun initView() {
}
}
\ No newline at end of file
package com.base.browserwhite.ui.activity.webbrowser
import com.base.browserwhite.databinding.ActivityWebBrowserBinding
import com.base.browserwhite.ui.activity.BaseActivity
class WebBrowserActivity : BaseActivity<ActivityWebBrowserBinding>() {
override val binding: ActivityWebBrowserBinding by lazy {
ActivityWebBrowserBinding.inflate(layoutInflater)
}
override fun initView() {
}
}
\ No newline at end of file
package com.base.browserwhite.ui.adapter
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.base.browserwhite.R
import com.base.browserwhite.bean.MediaBean
import com.base.browserwhite.databinding.ItemMediaRecentBinding
import com.base.browserwhite.utils.XmlEx.inflate
class MediaAdapter : RecyclerView.Adapter<MediaAdapter.MediaViewHolder>() {
private val beanList = arrayListOf<MediaBean>()
inner class MediaViewHolder(view: View) : ViewHolder(view)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MediaViewHolder {
return MediaViewHolder(R.layout.item_media_recent.inflate(parent))
}
override fun getItemCount(): Int {
return beanList.size
}
override fun onBindViewHolder(holder: MediaViewHolder, position: Int) {
val binding = ItemMediaRecentBinding.bind(holder.itemView)
}
}
\ No newline at end of file
package com.base.browserwhite.ui.adapter
import android.annotation.SuppressLint
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.base.browserwhite.R
import com.base.browserwhite.bean.WebSiteBean
import com.base.browserwhite.databinding.ItemWebsiteGridBinding
import com.base.browserwhite.utils.LogEx
import com.base.browserwhite.utils.XmlEx.inflate
class WebsiteAdapter : RecyclerView.Adapter<WebsiteAdapter.WebSiteViewHolder>() {
private val TAG = "WebsiteAdapter"
private val beanList = arrayListOf<WebSiteBean>()
inner class WebSiteViewHolder(view: View) : ViewHolder(view) {
var canDrag = true
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WebSiteViewHolder {
return WebSiteViewHolder(R.layout.item_website_grid.inflate(parent))
}
override fun getItemCount(): Int {
return beanList.size
}
override fun onBindViewHolder(holder: WebSiteViewHolder, position: Int) {
val binding = ItemWebsiteGridBinding.bind(holder.itemView)
val bean = beanList[position]
binding.ivIcon.setImageResource(bean.icon)
binding.tvName.text = bean.name
holder.canDrag = !bean.increase
}
@SuppressLint("NotifyDataSetChanged")
fun setData(webSiteList: List<WebSiteBean>) {
beanList.clear()
beanList.addAll(webSiteList)
notifyDataSetChanged()
}
fun changeBeanPosition(oldPosition: Int, newPosition: Int) {
LogEx.logDebug(TAG, "oldPosition=$oldPosition newPosition=$newPosition")
val bean = beanList[oldPosition]
beanList.remove(bean)
beanList.add(newPosition, bean)
}
}
\ No newline at end of file
package com.base.browserwhite.ui.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding
abstract class BaseFragment<T : ViewBinding> : Fragment() {
protected abstract val binding: T
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setView()
setListener()
}
protected abstract fun setView()
protected open fun setListener() {}
}
\ No newline at end of file
package com.base.browserwhite.ui.fragment
import android.annotation.SuppressLint
import android.app.usage.StorageStatsManager
import android.os.Build
import android.os.Environment
import android.os.StatFs
import android.os.storage.StorageManager
import androidx.appcompat.app.AppCompatActivity
import com.base.browserwhite.databinding.FragmentFileBinding
import com.base.browserwhite.utils.KotlinExt.toFormatSize
import java.io.File
class FileFragment : BaseFragment<FragmentFileBinding>() {
override val binding: FragmentFileBinding by lazy {
FragmentFileBinding.inflate(layoutInflater)
}
override fun setView() {
showStorage()
}
@SuppressLint("SetTextI18n")
private fun showStorage() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val storageStatsManager = requireContext().getSystemService(AppCompatActivity.STORAGE_STATS_SERVICE) as StorageStatsManager
Thread {
val totalBytes = storageStatsManager.getTotalBytes(StorageManager.UUID_DEFAULT)
val usedBytes = totalBytes - storageStatsManager.getFreeBytes(StorageManager.UUID_DEFAULT)
binding.root.post {
binding.tvUsedStorage.text = usedBytes.toFormatSize()
binding.tvTotalStorage.text = " / " + totalBytes.toFormatSize()
}
}.start()
} else {
val path1: File = Environment.getDataDirectory()
val stat1 = StatFs(path1.path)
val path2: File = Environment.getExternalStorageDirectory()
val stat2 = StatFs(path2.path)
val totalSize = (stat1.totalBytes + stat2.totalBytes).toFormatSize()
val usedSize = ((stat1.totalBytes + stat2.totalBytes) - (stat1.availableBytes + stat2.availableBytes)).toFormatSize()
binding.tvUsedStorage.text = usedSize
binding.tvTotalStorage.text = " / $totalSize"
}
}
}
\ No newline at end of file
package com.base.browserwhite.ui.fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import com.base.browserwhite.R
import com.base.browserwhite.bean.WebSiteBean
import com.base.browserwhite.databinding.FragmentHomeBinding
import com.base.browserwhite.ui.adapter.WebsiteAdapter
import com.base.browserwhite.ui.views.itemtouch.MyItemTouchHelperCallBack
class HomeFragment : BaseFragment<FragmentHomeBinding>() {
override val binding: FragmentHomeBinding by lazy {
FragmentHomeBinding.inflate(layoutInflater)
}
private lateinit var websiteAdapter: WebsiteAdapter
private lateinit var itemTouchHelper: ItemTouchHelper
override fun setView() {
binding.rvWeb.layoutManager = GridLayoutManager(requireContext(), 4, LinearLayoutManager.VERTICAL, false)
websiteAdapter = WebsiteAdapter()
binding.rvWeb.adapter = websiteAdapter
itemTouchHelper = ItemTouchHelper(MyItemTouchHelperCallBack())
itemTouchHelper.attachToRecyclerView(binding.rvWeb)
val recommendWebSite = listOf(
WebSiteBean("Amazon", R.mipmap.amazon),
WebSiteBean("Youtube", R.mipmap.youtube),
WebSiteBean("ChatGPT", R.mipmap.chatgpt),
WebSiteBean("Bing", R.mipmap.bing),
WebSiteBean("Twitter", R.mipmap.twitter),
WebSiteBean("Wikipedia", R.mipmap.wikipedia),
WebSiteBean("Facebook", R.mipmap.facebook),
WebSiteBean("Ebay", R.mipmap.ebay),
WebSiteBean("Tiktok", R.mipmap.tiktok),
WebSiteBean("Whatsapp", R.mipmap.whatsapp),
WebSiteBean("Increase", R.mipmap.increase).apply { increase = true },
)
websiteAdapter.setData(recommendWebSite)
}
}
\ No newline at end of file
package com.base.browserwhite.ui.views.itemtouch
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import com.base.browserwhite.ui.adapter.WebsiteAdapter
class MyItemTouchHelperCallBack : ItemTouchHelper.Callback() {
private val TAG = "MyItemTouchHelperCallBack"
/**
* 设置拖拽和item滑动的可支持方向
*/
override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
if (!(viewHolder as WebsiteAdapter.WebSiteViewHolder).canDrag) {
return makeMovementFlags(ItemTouchHelper.ACTION_STATE_IDLE, 0) // 不允许拖动
}
//支持上下左右拖动
//ACTION_STATE_IDLE item默认滑动方向
return makeMovementFlags(
ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.START or ItemTouchHelper.END,
ItemTouchHelper.ACTION_STATE_IDLE
)
}
/**
* 拖拽结束后(手指抬起)会回调的方法
*/
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
//更新item holder对应位置
recyclerView.adapter?.notifyItemMoved(
viewHolder.adapterPosition,
target.adapterPosition
)
//todo 更新recycleView中数据的位置
(recyclerView.adapter as WebsiteAdapter).changeBeanPosition(viewHolder.layoutPosition, target.layoutPosition)
return true
}
/**
* 侧滑回调
*/
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) = Unit
/**
* 长点击拖动
*/
override fun isLongPressDragEnabled() = true
/**
* 可结束拖动
*/
override fun canDropOver(
recyclerView: RecyclerView,
current: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return (target as WebsiteAdapter.WebSiteViewHolder).canDrag
}
}
\ No newline at end of file
package com.base.browserwhite.utils
import android.content.Intent
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultCaller
import androidx.activity.result.contract.ActivityResultContracts
class ActivityLauncher(activityResultCaller: ActivityResultCaller) {
//region 权限
private var permissionCallback: ActivityResultCallback<Map<String, Boolean>>? = null
private val permissionLauncher =
activityResultCaller.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result: Map<String, Boolean> ->
permissionCallback?.onActivityResult(result)
}
fun launch(
permissionArray: Array<String>,
permissionCallback: ActivityResultCallback<Map<String, Boolean>>?
) {
this.permissionCallback = permissionCallback
permissionLauncher.launch(permissionArray)
}
//endregion
//region intent跳转
private var activityResultCallback: ActivityResultCallback<ActivityResult>? = null
private val intentLauncher =
activityResultCaller.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult: ActivityResult ->
activityResultCallback?.onActivityResult(activityResult)
}
/**
* it.resultCode == Activity.RESULT_OK
*/
fun launch(
intent: Intent,
activityResultCallback: ActivityResultCallback<ActivityResult>? = null
) {
this.activityResultCallback = activityResultCallback
intentLauncher.launch(intent)
}
//endregion
//region saf
// private var safResultCallback: ActivityResultCallback<Uri?>? = null
// private val safLauncher =
// activityResultCaller.registerForActivityResult(
// ActivityResultContracts.OpenDocument(),
// ) { uri ->
// safResultCallback?.onActivityResult(uri)
// }
//
// fun launch(array: Array<String>, safResultCallback: ActivityResultCallback<Uri?>?) {
// this.safResultCallback = safResultCallback
// safLauncher.launch(array)
// }
//end region
}
\ No newline at end of file
package com.base.browserwhite.utils;
import android.app.Activity;
import java.util.Stack;
public class ActivityManagerUtils {
private static ActivityManagerUtils instance;
private Stack<Activity> activityStack = new Stack<>();
private ActivityManagerUtils() {
}
public static ActivityManagerUtils getInstance() {
if (instance == null) {
instance = new ActivityManagerUtils();
}
return instance;
}
/**
* 添加Activity到堆栈
*/
public void addActivity(Activity activity) {
activityStack.add(activity);
}
/**
* 移除Activity从堆栈
*/
public void removeActivity(Activity activity) {
activityStack.remove(activity);
}
/**
* 获取当前Activity(堆栈中最后一个压入的)
*/
public Activity getCurrentActivity() {
return activityStack.lastElement();
}
/**
* 结束指定的Activity
*/
public void finishActivity(Activity activity) {
if (activity != null) {
activityStack.remove(activity);
activity.finish();
}
}
/**
* 结束所有Activity
*/
public void finishAllActivity() {
for (Activity activity : activityStack) {
if (activity != null) {
activity.finish();
}
}
activityStack.clear();
}
/**
* 检查Activity是否存在于堆栈中
*/
public boolean isActivityInStack(Class<?> cls) {
boolean isExist = false;
if (cls != null) {
for (Activity activity : activityStack) {
if (cls.equals(activity.getClass())) {
isExist = true;
break;
}
}
}
return isExist;
}
public Activity getTopActivity() {
if (activityStack.empty()) {
return null;
} else {
return activityStack.peek();
}
}
}
\ No newline at end of file
package com.base.browserwhite.utils
//noinspection SuspiciousImport
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.res.Resources
import android.graphics.Color
import android.os.Build
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import androidx.annotation.ColorInt
@Suppress("DEPRECATION")
@SuppressLint("ObsoleteSdkInt")
object BarUtils {
fun setStatusBarLightMode(activity: Activity, isLightMode: Boolean) {
setStatusBarLightMode(activity.window, isLightMode)
}
private fun setStatusBarLightMode(window: Window, isLightMode: Boolean) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val decorView = window.decorView
var vis = decorView.systemUiVisibility
vis = if (isLightMode) {
vis or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
} else {
vis and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
}
decorView.systemUiVisibility = vis
}
}
fun setStatusBarColor(activity: Activity, @ColorInt color: Int): View? {
return setStatusBarColor(activity, color, false)
}
@Suppress("SameParameterValue")
private fun setStatusBarColor(activity: Activity, @ColorInt color: Int, isDecor: Boolean): View? {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return null
transparentStatusBar(activity)
return applyStatusBarColor(activity, color, isDecor)
}
private fun applyStatusBarColor(activity: Activity, color: Int, isDecor: Boolean): View {
return applyStatusBarColor(activity.window, color, isDecor)
}
private fun transparentStatusBar(activity: Activity) {
transparentStatusBar(activity.window)
}
private fun transparentStatusBar(window: Window) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
val option = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
val vis = window.decorView.systemUiVisibility
window.decorView.systemUiVisibility = option or vis
window.statusBarColor = Color.TRANSPARENT
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}
}
private fun applyStatusBarColor(window: Window, color: Int, isDecor: Boolean): View {
val parent =
if (isDecor) window.decorView as ViewGroup else (window.findViewById<View>(android.R.id.content) as ViewGroup)
var fakeStatusBarView =
parent.findViewWithTag<View>(TAG_STATUS_BAR)
if (fakeStatusBarView != null) {
if (fakeStatusBarView.visibility == View.GONE) {
fakeStatusBarView.visibility = View.VISIBLE
}
fakeStatusBarView.setBackgroundColor(color)
} else {
fakeStatusBarView = createStatusBarView(window.context, color)
parent.addView(fakeStatusBarView)
}
return fakeStatusBarView
}
private fun createStatusBarView(context: Context, color: Int): View {
val statusBarView = View(context)
statusBarView.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight()
)
statusBarView.setBackgroundColor(color)
statusBarView.tag = TAG_STATUS_BAR
return statusBarView
}
///////////////////////////////////////////////////////////////////////////
// status bar
///////////////////////////////////////////////////////////////////////////
private const val TAG_STATUS_BAR = "TAG_STATUS_BAR"
@SuppressLint("InternalInsetResource", "DiscouragedApi")
fun getStatusBarHeight(): Int {
val resources = Resources.getSystem()
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
return resources.getDimensionPixelSize(resourceId)
}
}
\ No newline at end of file
package com.base.browserwhite.utils
import android.graphics.Bitmap
import android.view.View
object FragmentCacheDrawHelper {
@Suppress("DEPRECATION")
fun getFragmentCacheBitmap(fragmentView: View): Bitmap? {
// 开启绘制缓存
fragmentView.setDrawingCacheEnabled(true)
// 获取绘制缓存的Bitmap
val bitmap = fragmentView.drawingCache
// 关闭和销毁绘制缓存
fragmentView.setDrawingCacheEnabled(false)
fragmentView.destroyDrawingCache()
return bitmap
}
}
\ No newline at end of file
package com.base.browserwhite.utils
import java.text.SimpleDateFormat
import java.util.Locale
object KotlinExt {
fun Number.toFormatSize(count: Int = 1): String {
var suffix = "B"
var fSize = this.toDouble()
if (fSize > 1024) {
suffix = "KB"
fSize /= 1024.0
}
if (fSize > 1024) {
suffix = "MB"
fSize /= 1024.0
}
if (fSize > 1024) {
suffix = "GB"
fSize /= 1024.0
}
return String.format("%.${count}f %s", fSize, suffix)
}
fun Long.toFormatTime(): String {
return SimpleDateFormat("MMM dd,yyyy", Locale.ENGLISH).format(this)
}
fun Array<String>.array2String(): String {
val stringBuilder = StringBuilder()
forEach {
stringBuilder.append(it)
}
return stringBuilder.toString()
}
}
\ No newline at end of file
package com.base.browserwhite.utils
import android.util.Log
import com.base.browserwhite.BuildConfig
object LogEx {
val isOpen = true
val filterTAG = arrayOf(
"FileHexEx",
)
fun logDebug(tag: String, content: String, isMust: Boolean = false) {
if (isMust) {
Log.e(tag, content)
} else {
if (!isOpen) return
if (filterTAG.contains(tag)) return
if (BuildConfig.DEBUG) {
Log.e(tag, content)
}
}
}
}
\ No newline at end of file
package com.base.browserwhite.utils
import android.view.View
internal fun View.scale(factor: Float) {
scaleX = factor
scaleY = factor
}
package com.base.browserwhite.utils
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
object XmlEx {
fun Int.inflate(parent: ViewGroup, attachToRoot: Boolean = false): View {
return LayoutInflater.from(parent.context).inflate(this, parent, attachToRoot)
}
fun Int.inflate(context: Context, attachToRoot: Boolean = false): View {
return LayoutInflater.from(context).inflate(this, null, attachToRoot)
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#71767B" android:state_selected="false" />
<item android:color="#0571ED" android:state_selected="true" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape
android:shape="oval"
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#00BF79"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#8338FF" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#E7EEF6" />
<corners android:radius="18dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="17.5dp" />
<solid android:color="#F95242" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#FF412F" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape
android:shape="oval"
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFC834"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<stroke
android:width="0.5dp"
android:color="#DEE9F4" />
<corners android:radius="15dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="1.5dp"
android:color="#070709" />
<corners android:radius="25dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@mipmap/tab_file_s"/>
<item android:state_selected="false" android:drawable="@mipmap/tab_file_n"/>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/tab_home_s" android:state_selected="true" />
<item android:drawable="@mipmap/tab_home_n" android:state_selected="false" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
\ 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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.activity.labelstack.LabelStackActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingVertical="30dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ 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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.activity.MainActivity">
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/ll_bottom_nav"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/ll_bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
tools:ignore="DisableBaselineAlignment">
<LinearLayout
android:id="@+id/ll_home"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:src="@drawable/bg_table_home"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="8dp"
android:paddingHorizontal="20dp"
android:paddingVertical="8dp"
android:text="Home"
android:textColor="@color/color_tab_text"
android:textSize="12sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_file"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:src="@drawable/bg_table_file"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="8dp"
android:paddingHorizontal="20dp"
android:paddingVertical="8dp"
android:text="File"
android:textColor="@color/color_tab_text"
android:textSize="12sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_label"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
tools:ignore="UseCompoundDrawables">
<TextView
android:id="@+id/tv_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:background="@mipmap/tab_label"
android:gravity="center"
android:textColor="@color/white"
android:textSize="12sp"
tools:ignore="ContentDescription"
tools:text="2" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="8dp"
android:paddingHorizontal="20dp"
android:paddingVertical="8dp"
android:text="Label"
android:textColor="@color/color_tab_text"
android:textSize="12sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_my"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:src="@mipmap/tab_my"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="8dp"
android:paddingHorizontal="20dp"
android:paddingVertical="8dp"
android:text="My"
android:textColor="@color/color_tab_text"
android:textSize="12sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
\ 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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.activity.news.NewsActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
\ 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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.activity.webbrowser.WebBrowserActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/card"
android:clickable="true"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="30dp"
android:background="#C1FA66"
app:cardCornerRadius="30dp">
<ImageView
android:id="@+id/iv"
android:layout_width="match_parent"
android:layout_height="600dp"
tools:ignore="ContentDescription" />
</androidx.cardview.widget.CardView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:orientation="horizontal">
<androidx.cardview.widget.CardView
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_marginVertical="4dp"
android:layout_marginStart="8dp">
<ImageView
android:id="@+id/iv"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="ContentDescription" />
</androidx.cardview.widget.CardView>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="5dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:text="Screenshot 20240805 103…"
android:textColor="#010101"
android:textSize="17sp"
tools:ignore="HardcodedText" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="358KB"
android:textColor="#6B6B6D"
android:textSize="14sp"
tools:ignore="HardcodedText" />
</LinearLayout>
<FrameLayout
android:id="@+id/fl_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="8dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/geduo"
tools:ignore="ContentDescription" />
</FrameLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp"
tools:ignore="ContentDescription"
tools:src="@mipmap/amazon" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8.5dp"
android:layout_marginBottom="5dp"
android:textColor="@color/black"
android:textSize="13sp"
tools:text="Amazon" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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