Skip to content

Commit dc5d598

Browse files
add the bottomsheet
1 parent 501eb51 commit dc5d598

File tree

7 files changed

+329
-14
lines changed

7 files changed

+329
-14
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,5 @@ Thumbs.db
4646
.gradle
4747
/build
4848
/captures
49-
49+
*/build
5050

app/build.gradle

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ apply plugin: 'kotlin-android-extensions'
66

77
android {
88
namespace "app.layout.motion.motionlayoutexample"
9-
compileSdkVersion 31
9+
compileSdkVersion 32
1010
defaultConfig {
1111
applicationId "app.layout.motion.motionlayoutexample"
1212
minSdkVersion 21
13-
targetSdkVersion 31
13+
targetSdkVersion 32
1414
versionCode 1
1515
versionName "1.0"
1616
vectorDrawables.useSupportLibrary = true
@@ -34,6 +34,7 @@ dependencies {
3434
implementation 'androidx.recyclerview:recyclerview:1.2.1'
3535
implementation 'de.hdodenhof:circleimageview:3.1.0'
3636
implementation 'androidx.fragment:fragment:1.4.1'
37+
implementation 'com.google.android.material:material:1.9.0'
3738
testImplementation 'junit:junit:4.13.2'
3839
androidTestImplementation 'androidx.test:runner:1.4.0'
3940
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package app.layout.motion.motionlayoutexample;
2+
3+
import android.annotation.SuppressLint
4+
import android.content.Context
5+
import android.util.AttributeSet
6+
import android.util.Log
7+
import android.view.MotionEvent
8+
import android.view.View
9+
import androidx.constraintlayout.motion.widget.MotionLayout
10+
import androidx.coordinatorlayout.widget.CoordinatorLayout
11+
import com.google.android.material.bottomsheet.BottomSheetBehavior
12+
13+
public class CustomBottomSheetBehavior<V : View>(context: Context, attrs: AttributeSet) : BottomSheetBehavior<V>(context, attrs) {
14+
private val TAG = "CustomBottomSheetBehavior"
15+
16+
@SuppressLint("LongLogTag")
17+
override fun onInterceptTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean {
18+
Log.i(TAG, "onInterceptTouchEvent, child: " + child + " MotionEvent:" + event)
19+
20+
if (state == BottomSheetBehavior.STATE_EXPANDED) {
21+
return false
22+
}
23+
24+
if (child is MotionLayout) {
25+
val shouldIntercept = child.progress < 1
26+
isDraggable = shouldIntercept
27+
return if (shouldIntercept) {
28+
super.onInterceptTouchEvent(parent, child, event)
29+
} else {
30+
false
31+
}
32+
}
33+
34+
return super.onInterceptTouchEvent(parent, child, event)
35+
}
36+
37+
38+
}

app/src/main/java/app/layout/motion/motionlayoutexample/DemoActivity.kt

+76
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
package app.layout.motion.motionlayoutexample
22

33
import android.animation.ArgbEvaluator
4+
import android.content.res.ColorStateList
45
import android.graphics.Color
56
import android.os.Build
67
import android.os.Bundle
78
import android.os.Handler
9+
import android.util.DisplayMetrics
10+
import android.view.MotionEvent
811
import android.view.View
912
import android.view.WindowManager
13+
import android.widget.LinearLayout
1014
import android.widget.TextView
1115
import androidx.appcompat.app.AppCompatActivity
1216
import androidx.constraintlayout.motion.widget.MotionLayout
1317
import androidx.core.content.ContextCompat
1418
import androidx.recyclerview.widget.LinearLayoutManager
1519
import androidx.recyclerview.widget.RecyclerView
20+
import com.google.android.material.bottomsheet.BottomSheetBehavior
21+
import com.google.android.material.shape.CornerFamily
22+
import com.google.android.material.shape.MaterialShapeDrawable
23+
import com.google.android.material.shape.ShapeAppearanceModel
1624

1725
class DemoActivity : AppCompatActivity(), MotionLayout.TransitionListener {
1826

@@ -26,6 +34,16 @@ class DemoActivity : AppCompatActivity(), MotionLayout.TransitionListener {
2634
private var startColor = Color.parseColor("#f48930")
2735
private var endColor = Color.parseColor("#b55fa3")
2836
private var currentColor = Color.parseColor("#b55fa3")
37+
private var bottomSheetBehavior: BottomSheetBehavior<LinearLayout>? = null
38+
39+
fun getScreenHeight(windowManager: WindowManager?): Int {
40+
if (windowManager == null) {
41+
return 0
42+
}
43+
val metrics = DisplayMetrics()
44+
windowManager.defaultDisplay.getMetrics(metrics)
45+
return metrics.heightPixels
46+
}
2947

3048
override fun onCreate(savedInstanceState: Bundle?) {
3149
super.onCreate(savedInstanceState)
@@ -34,6 +52,51 @@ class DemoActivity : AppCompatActivity(), MotionLayout.TransitionListener {
3452
setTheme()
3553
setContentView(layout)
3654
initViews()
55+
56+
// Initialize the bottom sheet behavior
57+
val bottomSheet: LinearLayout? = findViewById(R.id.bottom_sheet)
58+
if (null!=bottomSheet) {
59+
val layoutParams = bottomSheet?.layoutParams
60+
layoutParams?.height = getScreenHeight(windowManager)
61+
bottomSheet?.layoutParams = layoutParams
62+
63+
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)
64+
// bottomSheetBehavior.isDraggable = false
65+
// Set the initial state of the bottom sheet
66+
bottomSheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
67+
68+
// Set the peek height (the height of the bottom sheet when it is collapsed)
69+
bottomSheetBehavior?.peekHeight = 100
70+
bottomSheetBehavior?.isFitToContents = false
71+
// Set the half expanded ratio (the ratio of the height of the bottom sheet when it is half expanded)
72+
bottomSheetBehavior?.halfExpandedRatio = 0.6f
73+
74+
val shapeAppearanceModel = ShapeAppearanceModel.Builder()
75+
.setTopLeftCorner(CornerFamily.ROUNDED, 36f)
76+
.setTopRightCorner(CornerFamily.ROUNDED, 36f)
77+
.build()
78+
79+
val materialShapeDrawable = MaterialShapeDrawable(shapeAppearanceModel).apply{
80+
fillColor = ColorStateList.valueOf(Color.WHITE) // Set the desired color
81+
}
82+
bottomSheet.background = materialShapeDrawable
83+
84+
// Set the bottom sheet callback to handle changes in state
85+
bottomSheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
86+
override fun onStateChanged(bottomSheet: View, newState: Int) {
87+
// Handle state change
88+
89+
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
90+
// bottomSheetBehavior.isDraggable=false
91+
}
92+
}
93+
94+
override fun onSlide(bottomSheet: View, slideOffset: Float) {
95+
// Handle slide
96+
}
97+
})
98+
}
99+
37100
recyclerView!!.apply {
38101
setHasFixedSize(true)
39102
adapter = DummyListAdapter()
@@ -67,11 +130,24 @@ class DemoActivity : AppCompatActivity(), MotionLayout.TransitionListener {
67130
motionLayout = findViewById(R.id.motionLayout)
68131
recyclerView = findViewById(R.id.recyclerView)
69132

133+
// Intercept the recyclerView onTouch event
134+
recyclerView?.setOnTouchListener { _, event ->
135+
if (bottomSheetBehavior?.state == BottomSheetBehavior.STATE_HALF_EXPANDED) {
136+
// Disable the recyclerView scroll event when the BottomSheet is in Half Expand
137+
return@setOnTouchListener true
138+
}
139+
return@setOnTouchListener false
140+
}
141+
70142
if (layout == R.layout.collapsing_toolbar_2) {
71143
titleTextView = findViewById(R.id.title)
72144
}
73145
}
74146

147+
override fun onTouchEvent(event: MotionEvent?): Boolean {
148+
return super.onTouchEvent(event)
149+
}
150+
75151
override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, progress: Float) {
76152
if (p0 == null)
77153
return

app/src/main/java/app/layout/motion/motionlayoutexample/MainActivity.kt

+60-10
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,66 @@ class MainActivity : AppCompatActivity() {
1313
private lateinit var mLayoutManager: LinearLayoutManager
1414

1515
private val mAdapterData: Array<MainAdapter.Demo> = arrayOf(
16-
MainAdapter.Demo("Basic Collapsing Toolbar", ExampleTypes.DEFAULT, R.layout.collapsing_toolbar),
17-
MainAdapter.Demo("Collapsing Toolbar w/ Text Interpolation", ExampleTypes.DEFAULT, R.layout.collapsing_toolbar_2),
18-
MainAdapter.Demo("Collapsing Toolbar w/ Cover Example", ExampleTypes.FULLSCREEN, R.layout.collapsing_toolbar_with_cover),
19-
MainAdapter.Demo("Complex Animation Example", ExampleTypes.WITHOUT_RECYCLER_VIEW, R.layout.complex_animation_example, ComplexAnimationActivity::class.java),
20-
MainAdapter.Demo("Multiple Animation Example", ExampleTypes.FULLSCREEN, R.layout.multiple_animation_example, ComplexAnimationActivity::class.java),
21-
MainAdapter.Demo("Basic Keyframe Example", ExampleTypes.WITHOUT_RECYCLER_VIEW, R.layout.basic_key_frame_example),
22-
MainAdapter.Demo("Basic Keyframe Example 2", ExampleTypes.WITHOUT_RECYCLER_VIEW, R.layout.basic_key_frame_example_2),
23-
MainAdapter.Demo("Notification Center Example", ExampleTypes.DEFAULT, R.layout.notification_center_example),
24-
MainAdapter.Demo("ViewPager Example", ExampleTypes.VIEW_PAGER, R.layout.viewpager_example, ViewPagerActivity::class.java),
25-
MainAdapter.Demo("Youtube Fragment Transition Example", ExampleTypes.FRAGMENT, R.layout.youtube_fragment_transition_example, FragmentActivity::class.java)
16+
MainAdapter.Demo(
17+
"Basic Collapsing Toolbar",
18+
ExampleTypes.DEFAULT,
19+
R.layout.collapsing_toolbar
20+
),
21+
MainAdapter.Demo(
22+
"Collapsing Toolbar w/ Text Interpolation",
23+
ExampleTypes.DEFAULT,
24+
R.layout.collapsing_toolbar_2
25+
),
26+
MainAdapter.Demo(
27+
"Collapsing Toolbar w/ Cover Example",
28+
ExampleTypes.FULLSCREEN,
29+
R.layout.collapsing_toolbar_with_cover
30+
),
31+
MainAdapter.Demo(
32+
"Collapsing Toolbar with BottomSheet " +
33+
"Example",
34+
ExampleTypes.FULLSCREEN,
35+
R.layout.collapsing_toolbar_with_cover_bottomsheet
36+
),
37+
MainAdapter.Demo(
38+
"Complex Animation Example",
39+
ExampleTypes.WITHOUT_RECYCLER_VIEW,
40+
R.layout.complex_animation_example,
41+
ComplexAnimationActivity::class.java
42+
),
43+
MainAdapter.Demo(
44+
"Multiple Animation Example",
45+
ExampleTypes.FULLSCREEN,
46+
R.layout.multiple_animation_example,
47+
ComplexAnimationActivity::class.java
48+
),
49+
MainAdapter.Demo(
50+
"Basic Keyframe Example",
51+
ExampleTypes.WITHOUT_RECYCLER_VIEW,
52+
R.layout.basic_key_frame_example
53+
),
54+
MainAdapter.Demo(
55+
"Basic Keyframe Example 2",
56+
ExampleTypes.WITHOUT_RECYCLER_VIEW,
57+
R.layout.basic_key_frame_example_2
58+
),
59+
MainAdapter.Demo(
60+
"Notification Center Example",
61+
ExampleTypes.DEFAULT,
62+
R.layout.notification_center_example
63+
),
64+
MainAdapter.Demo(
65+
"ViewPager Example",
66+
ExampleTypes.VIEW_PAGER,
67+
R.layout.viewpager_example,
68+
ViewPagerActivity::class.java
69+
),
70+
MainAdapter.Demo(
71+
"Youtube Fragment Transition Example",
72+
ExampleTypes.FRAGMENT,
73+
R.layout.youtube_fragment_transition_example,
74+
FragmentActivity::class.java
75+
)
2676

2777

2878
)

0 commit comments

Comments
 (0)