提交可扩展视图。
This commit is contained in:
parent
6f38bcd9b9
commit
f2e4a5250a
6
.idea/compiler.xml
Normal file
6
.idea/compiler.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<bytecodeTargetLevel target="17" />
|
||||||
|
</component>
|
||||||
|
</project>
|
20
.idea/gradle.xml
Normal file
20
.idea/gradle.xml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GradleSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<GradleProjectSettings>
|
||||||
|
<option name="testRunner" value="GRADLE" />
|
||||||
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="gradleJvm" value="jbr-17" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
<option value="$PROJECT_DIR$/app" />
|
||||||
|
<option value="$PROJECT_DIR$/scalableLayout" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</GradleProjectSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/kotlinc.xml
Normal file
6
.idea/kotlinc.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="KotlinJpsPluginSettings">
|
||||||
|
<option name="version" value="1.9.0" />
|
||||||
|
</component>
|
||||||
|
</project>
|
7
.idea/misc.xml
Normal file
7
.idea/misc.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -40,12 +40,14 @@ android {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
|
|
||||||
implementation("androidx.core:core-ktx:1.9.0")
|
implementation("androidx.core:core-ktx:1.9.0")
|
||||||
implementation("androidx.appcompat:appcompat:1.6.1")
|
implementation("androidx.appcompat:appcompat:1.6.1")
|
||||||
implementation("com.google.android.material:material:1.8.0")
|
implementation("com.google.android.material:material:1.8.0")
|
||||||
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
|
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
|
||||||
implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
|
implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
|
||||||
implementation("androidx.navigation:navigation-ui-ktx:2.5.3")
|
implementation("androidx.navigation:navigation-ui-ktx:2.5.3")
|
||||||
|
implementation(project(mapOf("path" to ":scalableLayout")))
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
package com.coldmint.scalableLayout
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.navigation.fragment.findNavController
|
|
||||||
import com.coldmint.scalableLayout.databinding.FragmentFirstBinding
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple [Fragment] subclass as the default destination in the navigation.
|
|
||||||
*/
|
|
||||||
class FirstFragment : Fragment() {
|
|
||||||
|
|
||||||
private var _binding: FragmentFirstBinding? = null
|
|
||||||
|
|
||||||
// This property is only valid between onCreateView and
|
|
||||||
// onDestroyView.
|
|
||||||
private val binding get() = _binding!!
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View? {
|
|
||||||
|
|
||||||
_binding = FragmentFirstBinding.inflate(inflater, container, false)
|
|
||||||
return binding.root
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
|
||||||
binding.buttonFirst.setOnClickListener {
|
|
||||||
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
_binding = null
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,7 +13,6 @@ import com.coldmint.scalableLayout.databinding.ActivityMainBinding
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var appBarConfiguration: AppBarConfiguration
|
|
||||||
private lateinit var binding: ActivityMainBinding
|
private lateinit var binding: ActivityMainBinding
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
@ -24,35 +23,6 @@ class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
setSupportActionBar(binding.toolbar)
|
setSupportActionBar(binding.toolbar)
|
||||||
|
|
||||||
val navController = findNavController(R.id.nav_host_fragment_content_main)
|
|
||||||
appBarConfiguration = AppBarConfiguration(navController.graph)
|
|
||||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
|
||||||
|
|
||||||
binding.fab.setOnClickListener { view ->
|
|
||||||
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
|
|
||||||
.setAction("Action", null).show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
|
||||||
// Inflate the menu; this adds items to the action bar if it is present.
|
|
||||||
menuInflater.inflate(R.menu.menu_main, menu)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
||||||
// Handle action bar item clicks here. The action bar will
|
|
||||||
// automatically handle clicks on the Home/Up button, so long
|
|
||||||
// as you specify a parent activity in AndroidManifest.xml.
|
|
||||||
return when (item.itemId) {
|
|
||||||
R.id.action_settings -> true
|
|
||||||
else -> super.onOptionsItemSelected(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSupportNavigateUp(): Boolean {
|
|
||||||
val navController = findNavController(R.id.nav_host_fragment_content_main)
|
|
||||||
return navController.navigateUp(appBarConfiguration)
|
|
||||||
|| super.onSupportNavigateUp()
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,44 +0,0 @@
|
||||||
package com.coldmint.scalableLayout
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.navigation.fragment.findNavController
|
|
||||||
import com.coldmint.scalableLayout.databinding.FragmentSecondBinding
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple [Fragment] subclass as the second destination in the navigation.
|
|
||||||
*/
|
|
||||||
class SecondFragment : Fragment() {
|
|
||||||
|
|
||||||
private var _binding: FragmentSecondBinding? = null
|
|
||||||
|
|
||||||
// This property is only valid between onCreateView and
|
|
||||||
// onDestroyView.
|
|
||||||
private val binding get() = _binding!!
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View? {
|
|
||||||
|
|
||||||
_binding = FragmentSecondBinding.inflate(inflater, container, false)
|
|
||||||
return binding.root
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
|
||||||
binding.buttonSecond.setOnClickListener {
|
|
||||||
findNavController().navigate(R.id.action_SecondFragment_to_FirstFragment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
_binding = null
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,15 +19,48 @@
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<include layout="@layout/content_main" />
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
<com.coldmint.scalablelayout.ScalableLayout
|
||||||
android:id="@+id/fab"
|
android:id="@+id/scalableLayout"
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:background="#03a9f4"
|
||||||
|
android:gravity="center"
|
||||||
|
android:maxWidth="180dp"
|
||||||
|
android:minWidth="30dp">
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/TextAppearance.Material3.BodyMedium"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom|end"
|
android:text="可改变宽度的区域"
|
||||||
android:layout_marginEnd="@dimen/fab_margin"
|
android:textColor="@color/white" />
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
app:srcCompat="@android:drawable/ic_dialog_email" />
|
</com.coldmint.scalablelayout.ScalableLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_toRightOf="@id/scalableLayout"
|
||||||
|
android:background="#90caf9"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/TextAppearance.Material3.BodyMedium"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="主内容"
|
||||||
|
android:textColor="@color/white" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -1,19 +0,0 @@
|
||||||
<?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"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
|
||||||
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/nav_host_fragment_content_main"
|
|
||||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
app:defaultNavHost="true"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:navGraph="@navigation/nav_graph" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
|
@ -1,35 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.core.widget.NestedScrollView 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"
|
|
||||||
tools:context=".FirstFragment">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:padding="16dp">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/button_first"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/next"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/textview_first"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textview_first"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:text="@string/lorem_ipsum"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/button_first" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
|
@ -1,35 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.core.widget.NestedScrollView 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"
|
|
||||||
tools:context=".SecondFragment">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:padding="16dp">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/button_second"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/previous"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/textview_second"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textview_second"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:text="@string/lorem_ipsum"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/button_second" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
|
@ -1,10 +0,0 @@
|
||||||
<menu 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"
|
|
||||||
tools:context="com.coldmint.scalableLayout.MainActivity">
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_settings"
|
|
||||||
android:orderInCategory="100"
|
|
||||||
android:title="@string/action_settings"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
</menu>
|
|
|
@ -1,28 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<navigation 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/nav_graph"
|
|
||||||
app:startDestination="@id/FirstFragment">
|
|
||||||
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/FirstFragment"
|
|
||||||
android:name="com.coldmint.scalableLayout.FirstFragment"
|
|
||||||
android:label="@string/first_fragment_label"
|
|
||||||
tools:layout="@layout/fragment_first">
|
|
||||||
|
|
||||||
<action
|
|
||||||
android:id="@+id/action_FirstFragment_to_SecondFragment"
|
|
||||||
app:destination="@id/SecondFragment" />
|
|
||||||
</fragment>
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/SecondFragment"
|
|
||||||
android:name="com.coldmint.scalableLayout.SecondFragment"
|
|
||||||
android:label="@string/second_fragment_label"
|
|
||||||
tools:layout="@layout/fragment_second">
|
|
||||||
|
|
||||||
<action
|
|
||||||
android:id="@+id/action_SecondFragment_to_FirstFragment"
|
|
||||||
app:destination="@id/FirstFragment" />
|
|
||||||
</fragment>
|
|
||||||
</navigation>
|
|
|
@ -2,4 +2,5 @@
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application") version "8.1.3" apply false
|
id("com.android.application") version "8.1.3" apply false
|
||||||
id("org.jetbrains.kotlin.android") version "1.9.0" apply false
|
id("org.jetbrains.kotlin.android") version "1.9.0" apply false
|
||||||
|
id("com.android.library") version "8.1.3" apply false
|
||||||
}
|
}
|
1
scalableLayout/.gitignore
vendored
Normal file
1
scalableLayout/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/build
|
43
scalableLayout/build.gradle.kts
Normal file
43
scalableLayout/build.gradle.kts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
plugins {
|
||||||
|
id("com.android.library")
|
||||||
|
id("org.jetbrains.kotlin.android")
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "com.coldmint.scalablelayout"
|
||||||
|
compileSdk = 33
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdk = 24
|
||||||
|
|
||||||
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
consumerProguardFiles("consumer-rules.pro")
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
implementation("androidx.core:core-ktx:1.9.0")
|
||||||
|
implementation("androidx.appcompat:appcompat:1.6.1")
|
||||||
|
implementation("com.google.android.material:material:1.8.0")
|
||||||
|
testImplementation("junit:junit:4.13.2")
|
||||||
|
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||||
|
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
||||||
|
}
|
0
scalableLayout/consumer-rules.pro
Normal file
0
scalableLayout/consumer-rules.pro
Normal file
21
scalableLayout/proguard-rules.pro
vendored
Normal file
21
scalableLayout/proguard-rules.pro
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# 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
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.coldmint.scalablelayout
|
||||||
|
|
||||||
|
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.coldmint.scalablelayout.test", appContext.packageName)
|
||||||
|
}
|
||||||
|
}
|
4
scalableLayout/src/main/AndroidManifest.xml
Normal file
4
scalableLayout/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
</manifest>
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.coldmint.scalablelayout
|
||||||
|
|
||||||
|
interface OnWidthChangeListener {
|
||||||
|
/**
|
||||||
|
* 当宽度改变时
|
||||||
|
*
|
||||||
|
* @param newWidth 新宽度
|
||||||
|
* @param minWidth 最小宽度
|
||||||
|
* @param maxWidth 最大宽度
|
||||||
|
*/
|
||||||
|
fun onChange(newWidth: Int, minWidth: Int, maxWidth: Int)
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
package com.coldmint.scalablelayout
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
|
||||||
|
class ScalableLayout : LinearLayout {
|
||||||
|
|
||||||
|
|
||||||
|
//最小宽度
|
||||||
|
var minWidth = 0
|
||||||
|
|
||||||
|
//最大宽度
|
||||||
|
var maxWidth = Int.MAX_VALUE
|
||||||
|
|
||||||
|
private var startX = 0f
|
||||||
|
private var onWidthChangeListener: OnWidthChangeListener? = null
|
||||||
|
|
||||||
|
constructor(context: Context?) : super(context)
|
||||||
|
|
||||||
|
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
||||||
|
init(attrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
||||||
|
context,
|
||||||
|
attrs,
|
||||||
|
defStyleAttr
|
||||||
|
) {
|
||||||
|
init(attrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
context: Context?,
|
||||||
|
attrs: AttributeSet?,
|
||||||
|
defStyleAttr: Int,
|
||||||
|
defStyleRes: Int
|
||||||
|
) : super(context, attrs, defStyleAttr, defStyleRes) {
|
||||||
|
init(attrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun init(attrs: AttributeSet?) {
|
||||||
|
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ScalableLayout)
|
||||||
|
minWidth = typedArray.getDimensionPixelSize(R.styleable.ScalableLayout_android_minWidth, 0)
|
||||||
|
maxWidth = typedArray.getDimensionPixelSize(
|
||||||
|
R.styleable.ScalableLayout_android_maxWidth,
|
||||||
|
Int.MAX_VALUE
|
||||||
|
)
|
||||||
|
typedArray.recycle()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||||
|
val widthSize = MeasureSpec.getSize(widthMeasureSpec)
|
||||||
|
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
|
||||||
|
var newWidth = widthSize
|
||||||
|
if (widthMode == MeasureSpec.AT_MOST) {
|
||||||
|
newWidth = widthSize.coerceAtMost(maxWidth)
|
||||||
|
newWidth = newWidth.coerceAtLeast(minWidth)
|
||||||
|
} else if (widthMode == MeasureSpec.UNSPECIFIED || widthMode == MeasureSpec.EXACTLY) {
|
||||||
|
newWidth = newWidth.coerceAtLeast(minWidth)
|
||||||
|
newWidth = newWidth.coerceAtMost(maxWidth)
|
||||||
|
}
|
||||||
|
val newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth, widthMode)
|
||||||
|
super.onMeasure(newWidthMeasureSpec, heightMeasureSpec)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||||
|
when (event.action) {
|
||||||
|
MotionEvent.ACTION_DOWN -> startX = event.rawX
|
||||||
|
MotionEvent.ACTION_MOVE -> {
|
||||||
|
val offsetX = event.rawX - startX
|
||||||
|
var newWidth = width + offsetX.toInt()
|
||||||
|
newWidth = minWidth.coerceAtLeast(newWidth)
|
||||||
|
newWidth = maxWidth.coerceAtMost(newWidth)
|
||||||
|
if (onWidthChangeListener != null) {
|
||||||
|
onWidthChangeListener!!.onChange(newWidth, minWidth, maxWidth)
|
||||||
|
}
|
||||||
|
val layoutParams = layoutParams
|
||||||
|
layoutParams.width = newWidth
|
||||||
|
setLayoutParams(layoutParams)
|
||||||
|
startX = event.rawX
|
||||||
|
}
|
||||||
|
|
||||||
|
MotionEvent.ACTION_UP -> {}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
8
scalableLayout/src/main/res/values/attrs.xml
Normal file
8
scalableLayout/src/main/res/values/attrs.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<declare-styleable name="ScalableLayout">
|
||||||
|
<attr name="android:minWidth" format="dimension" />
|
||||||
|
<attr name="android:maxWidth" format="dimension" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.coldmint.scalablelayout
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
class ExampleUnitTest {
|
||||||
|
@Test
|
||||||
|
fun addition_isCorrect() {
|
||||||
|
assertEquals(4, 2 + 2)
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,4 +23,4 @@ dependencyResolutionManagement {
|
||||||
|
|
||||||
rootProject.name = "ScalableLayout"
|
rootProject.name = "ScalableLayout"
|
||||||
include(":app")
|
include(":app")
|
||||||
|
include(":scalableLayout")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user