增加新增按钮
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
package com.navinfo.volvo
|
package com.navinfo.volvo
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.navigation.Navigation
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
import androidx.navigation.ui.AppBarConfiguration
|
import androidx.navigation.ui.AppBarConfiguration
|
||||||
import androidx.navigation.ui.setupActionBarWithNavController
|
import androidx.navigation.ui.setupActionBarWithNavController
|
||||||
@@ -27,10 +29,17 @@ class MainActivity : AppCompatActivity() {
|
|||||||
// menu should be considered as top level destinations.
|
// menu should be considered as top level destinations.
|
||||||
val appBarConfiguration = AppBarConfiguration(
|
val appBarConfiguration = AppBarConfiguration(
|
||||||
setOf(
|
setOf(
|
||||||
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
|
R.id.navigation_home,
|
||||||
|
R.id.navigation_dashboard,
|
||||||
|
R.id.navigation_notifications
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||||
navView.setupWithNavController(navController)
|
navView.setupWithNavController(navController)
|
||||||
|
findViewById<View>(R.id.fab_new_message).apply {
|
||||||
|
this.setOnClickListener {
|
||||||
|
navController.navigate(R.id.fab_new_message)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
package com.navinfo.volvo.ui.widget
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.Rect
|
|
||||||
import android.util.AttributeSet
|
|
||||||
import android.view.*
|
|
||||||
import android.widget.Scroller
|
|
||||||
import androidx.core.view.forEach
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import java.lang.Math.abs
|
|
||||||
|
|
||||||
class SlideRecyclerView @JvmOverloads constructor(
|
|
||||||
context: Context,
|
|
||||||
attrs: AttributeSet? = null,
|
|
||||||
defStyleAttr: Int = 0
|
|
||||||
) : RecyclerView(context, attrs, defStyleAttr) {
|
|
||||||
//系统最小移动距离
|
|
||||||
private val mTouchSlop = ViewConfiguration.get(context).scaledTouchSlop
|
|
||||||
|
|
||||||
//最小有效速度
|
|
||||||
private val mMinVelocity = 600
|
|
||||||
|
|
||||||
//增加手势控制,双击快速完成侧滑
|
|
||||||
private var isDoubleClick = false
|
|
||||||
private var mGestureDetector: GestureDetector =
|
|
||||||
GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
|
|
||||||
override fun onDoubleTap(e: MotionEvent?): Boolean {
|
|
||||||
e?.let { event ->
|
|
||||||
getSelectItem(event)
|
|
||||||
mItem?.let {
|
|
||||||
val deleteWith = it.getChildAt(it.childCount - 1).width
|
|
||||||
//触发移动至完全展开deleteWidth
|
|
||||||
if (it.scrollX == 0) {
|
|
||||||
mScroller.startScroll(0, 0, deleteWith, 0)
|
|
||||||
} else {
|
|
||||||
mScroller.startScroll(it.scrollX, 0, -it.scrollX, 0)
|
|
||||||
}
|
|
||||||
isDoubleClick = true
|
|
||||||
invalidate()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//不进行拦截,只作为工具判断下双击
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
//使用速度控制器,增加侧滑速度判定滑动成功,
|
|
||||||
//VelocityTracker 由native实现,需要及时释放内存
|
|
||||||
private var mVelocityTracker: VelocityTracker? = null
|
|
||||||
|
|
||||||
//流畅滑动
|
|
||||||
private var mScroller = Scroller(context)
|
|
||||||
|
|
||||||
//当前选中item
|
|
||||||
private var mItem: ViewGroup? = null
|
|
||||||
|
|
||||||
//上次按下的横坐标
|
|
||||||
private var mLastX = 0f
|
|
||||||
|
|
||||||
//当前RecyclerView被上层ViewGroup分发到事件,所有事件都会通过dispatchTouchEvent给到
|
|
||||||
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
|
|
||||||
mGestureDetector.onTouchEvent(ev)
|
|
||||||
return super.dispatchTouchEvent(ev)
|
|
||||||
}
|
|
||||||
|
|
||||||
//viewGroup对子控件的事件拦截,一旦拦截,后续事件序列不会再调用onInterceptTouchEvent
|
|
||||||
override fun onInterceptTouchEvent(e: MotionEvent?): Boolean {
|
|
||||||
e?.let {
|
|
||||||
when (e.action) {
|
|
||||||
MotionEvent.ACTION_DOWN -> {
|
|
||||||
getSelectItem(e)
|
|
||||||
mLastX = e.x
|
|
||||||
}
|
|
||||||
MotionEvent.ACTION_MOVE -> {
|
|
||||||
//移动控件
|
|
||||||
return moveItem(e)
|
|
||||||
}
|
|
||||||
// MotionEvent.ACTION_UP -> {
|
|
||||||
// stopMove(e)
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onInterceptTouchEvent(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
|
||||||
override fun onTouchEvent(e: MotionEvent?): Boolean {
|
|
||||||
e?.let {
|
|
||||||
when (e.action) {
|
|
||||||
MotionEvent.ACTION_MOVE -> {
|
|
||||||
moveItem(e)
|
|
||||||
mLastX = e.x
|
|
||||||
}
|
|
||||||
MotionEvent.ACTION_UP -> {
|
|
||||||
stopMove()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onTouchEvent(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
//活动结束
|
|
||||||
//判断一下结束的位置,补充或恢复位置
|
|
||||||
private fun stopMove() {
|
|
||||||
mItem?.let {
|
|
||||||
//如果移动过半,判定左划成功
|
|
||||||
val deleteWidth = it.getChildAt(it.childCount - 1).width
|
|
||||||
//如果整个移动过程速度大于600,也判定滑动成功
|
|
||||||
//注意如果没有拦截ACTION_MOVE,mVelocityTracker是没有初始化的
|
|
||||||
var velocity = 0f
|
|
||||||
mVelocityTracker?.let { tracker ->
|
|
||||||
tracker.computeCurrentVelocity(1000)
|
|
||||||
velocity = tracker.xVelocity
|
|
||||||
}
|
|
||||||
//判断结束情况,移动过半或者向左速度很快都展开
|
|
||||||
if ((abs(it.scrollX) >= deleteWidth / 2f) || (velocity < -mMinVelocity)) {
|
|
||||||
//触发移动至完全展开
|
|
||||||
mScroller.startScroll(it.scrollX, 0, deleteWidth - it.scrollX, 0)
|
|
||||||
invalidate()
|
|
||||||
} else {
|
|
||||||
//如果移动未过半应恢复状态
|
|
||||||
mScroller.startScroll(it.scrollX, 0, -it.scrollX, 0)
|
|
||||||
invalidate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//清除状态
|
|
||||||
mLastX = 0f
|
|
||||||
//mVeloctityTracker由native实现,需要及时释放
|
|
||||||
mVelocityTracker?.apply {
|
|
||||||
clear()
|
|
||||||
recycle()
|
|
||||||
}
|
|
||||||
mVelocityTracker = null
|
|
||||||
}
|
|
||||||
|
|
||||||
//移动Item
|
|
||||||
//绝对值小于删除按钮长度随便移动,大于则不移动
|
|
||||||
@SuppressLint("Recycle")
|
|
||||||
private fun moveItem(e: MotionEvent): Boolean {
|
|
||||||
mItem?.let {
|
|
||||||
val dx = mLastX - e.x
|
|
||||||
//最小的移动距离应该舍弃,onInterceptTouchEvent不拦截,onTouchEvent内才更新mLastX
|
|
||||||
// if (abs(dx) > mTouchSlop) {
|
|
||||||
//检查mItem移动后应该在【-deleteLength,0】内
|
|
||||||
val deleteWith = it.getChildAt(it.childCount - 1).width
|
|
||||||
if ((it.scrollX + dx) <= deleteWith && (it.scrollX + dx) >= 0) {
|
|
||||||
//触发移动
|
|
||||||
it.scrollBy(dx.toInt(), 0)
|
|
||||||
//触发速度计算
|
|
||||||
//这里Rectycle不存在问题,一旦返回true,就会拦截事件,就会到达ACTION_UP去回收
|
|
||||||
mVelocityTracker = mVelocityTracker ?: VelocityTracker.obtain()
|
|
||||||
mVelocityTracker!!.addMovement(e)
|
|
||||||
return true
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取点击位置
|
|
||||||
//通过点击的y坐标除以Item高度得出
|
|
||||||
private fun getSelectItem(e: MotionEvent) {
|
|
||||||
val frame = Rect()
|
|
||||||
mItem = null
|
|
||||||
forEach {
|
|
||||||
if (it.visibility != GONE) {
|
|
||||||
it.getHitRect(frame)
|
|
||||||
if (frame.contains(e.x.toInt(), e.y.toInt())) {
|
|
||||||
mItem = it as ViewGroup
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//流畅地滑动
|
|
||||||
override fun computeScroll() {
|
|
||||||
if (mScroller.computeScrollOffset()) {
|
|
||||||
mItem?.scrollBy(mScroller.currX, mScroller.currY)
|
|
||||||
postInvalidate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
5
app/src/main/res/drawable/ic_add_24dp.xml
Normal file
5
app/src/main/res/drawable/ic_add_24dp.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#000000"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
|
||||||
|
</vector>
|
||||||
5
app/src/main/res/drawable/ic_baseline_person_24.xml
Normal file
5
app/src/main/res/drawable/ic_baseline_person_24.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#000000"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
|
||||||
|
</vector>
|
||||||
@@ -3,8 +3,7 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/container"
|
android:id="@+id/container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
>
|
|
||||||
|
|
||||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
android:id="@+id/nav_view"
|
android:id="@+id/nav_view"
|
||||||
@@ -13,6 +12,7 @@
|
|||||||
android:layout_marginStart="0dp"
|
android:layout_marginStart="0dp"
|
||||||
android:layout_marginEnd="0dp"
|
android:layout_marginEnd="0dp"
|
||||||
android:background="?android:attr/windowBackground"
|
android:background="?android:attr/windowBackground"
|
||||||
|
app:labelVisibilityMode="labeled"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
@@ -30,4 +30,15 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:navGraph="@navigation/mobile_navigation" />
|
app:navGraph="@navigation/mobile_navigation" />
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/fab_new_message"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:src="@drawable/ic_add_24dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:elevation="8dp"
|
||||||
|
/>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -5,15 +5,20 @@
|
|||||||
android:id="@+id/navigation_home"
|
android:id="@+id/navigation_home"
|
||||||
android:icon="@drawable/ic_home_black_24dp"
|
android:icon="@drawable/ic_home_black_24dp"
|
||||||
android:title="@string/title_home" />
|
android:title="@string/title_home" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/navigation_dashboard"
|
android:id="@+id/navigation_dashboard"
|
||||||
android:icon="@drawable/ic_dashboard_black_24dp"
|
android:icon="@drawable/ic_dashboard_black_24dp"
|
||||||
android:title="@string/title_dashboard" />
|
android:title="@string/title_dashboard" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/navigation_none"
|
||||||
|
android:icon="@color/black"
|
||||||
|
android:title=" " />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/navigation_notifications"
|
android:id="@+id/navigation_notifications"
|
||||||
android:icon="@drawable/ic_notifications_black_24dp"
|
android:icon="@drawable/ic_notifications_black_24dp"
|
||||||
android:title="@string/title_notifications" />
|
android:title="@string/title_notifications" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/navigation_my"
|
||||||
|
android:icon="@drawable/ic_baseline_person_24"
|
||||||
|
android:title="@string/my" />
|
||||||
</menu>
|
</menu>
|
||||||
@@ -9,7 +9,12 @@
|
|||||||
android:id="@+id/navigation_home"
|
android:id="@+id/navigation_home"
|
||||||
android:name="com.navinfo.volvo.ui.home.HomeFragment"
|
android:name="com.navinfo.volvo.ui.home.HomeFragment"
|
||||||
android:label="@string/title_home"
|
android:label="@string/title_home"
|
||||||
tools:layout="@layout/fragment_home" />
|
tools:layout="@layout/fragment_home" >
|
||||||
|
<action
|
||||||
|
android:id="@+id/to_fab_new_message"
|
||||||
|
app:destination="@id/fab_new_message"
|
||||||
|
/>
|
||||||
|
</fragment>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/navigation_dashboard"
|
android:id="@+id/navigation_dashboard"
|
||||||
@@ -17,6 +22,12 @@
|
|||||||
android:label="@string/title_dashboard"
|
android:label="@string/title_dashboard"
|
||||||
tools:layout="@layout/fragment_dashboard" />
|
tools:layout="@layout/fragment_dashboard" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/fab_new_message"
|
||||||
|
android:name="com.navinfo.volvo.ui.dashboard.DashboardFragment"
|
||||||
|
android:label="@string/title_dashboard"
|
||||||
|
tools:layout="@layout/fragment_dashboard" />
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/navigation_notifications"
|
android:id="@+id/navigation_notifications"
|
||||||
android:name="com.navinfo.volvo.ui.notifications.NotificationsFragment"
|
android:name="com.navinfo.volvo.ui.notifications.NotificationsFragment"
|
||||||
|
|||||||
@@ -5,4 +5,5 @@
|
|||||||
<string name="title_notifications">Notifications</string>
|
<string name="title_notifications">Notifications</string>
|
||||||
<string name="delete">删除</string>
|
<string name="delete">删除</string>
|
||||||
<string name="share">分享</string>
|
<string name="share">分享</string>
|
||||||
|
<string name="my">我的</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -5,4 +5,5 @@
|
|||||||
<string name="title_notifications">Notifications</string>
|
<string name="title_notifications">Notifications</string>
|
||||||
<string name="delete">Del</string>
|
<string name="delete">Del</string>
|
||||||
<string name="share">Share</string>
|
<string name="share">Share</string>
|
||||||
|
<string name="my">My</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user