提交 5fd99792 作者: enjoy

优化INIT

上级 cf6523fd
package com.juling.pro_juliao.ui
import android.util.Log
import android.os.Bundle
import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import com.alibaba.android.arouter.facade.annotation.Route
import com.juling.ipage.ui.NavigationActivity
import com.juling.work_onepage.ui.FriendFragment
import com.work.provide_tool.general.RouterPath
@Route(path = RouterPath.IPAGE_MAINACTIVITY)
class MainActivity : NavigationActivity<Fragment>() {
override fun onCreate(savedInstanceState: Bundle?) {
titleFlag = false
super.onCreate(savedInstanceState)
}
override fun providerFragment(): List<Fragment> {
return ArrayList<Fragment>().apply {
for (i in 0..2)
add(TtFrag())
for (i in 0..2){
add(FriendFragment())
}
}
}
fun aa(){
var a = "1+1+1+1+1+1+1+1 "
override fun initOtherUi() {
setPos(-1,0)
}
override fun initData() {
}
override fun initEvent() {
}
}
\ No newline at end of file
package com.juling.pro_juliao.ui
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.alibaba.android.arouter.facade.annotation.Route
import com.juling.pro_juliao.R
import com.work.provide_tool.general.RouterPath.WIDGET_MAIN
@Route(path = WIDGET_MAIN)
class Tt :AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.tta)
}
}
\ No newline at end of file
package com.juling.pro_juliao.ui
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.juling.pro_juliao.R
class TtFrag :Fragment(){
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.frag_tt,null)
}
}
\ No newline at end of file
......@@ -52,5 +52,8 @@ ext{
//适配
"auto_ui":"com.github.JessYanCoding:AndroidAutoSize:v1.2.1",
//圆图
"round_iv":"de.hdodenhof:circleimageview:3.1.0"
]
}
\ No newline at end of file
......@@ -4,16 +4,25 @@ import android.view.LayoutInflater
import android.view.View
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import com.work.provide_origin.R
abstract class GeneralAgentFragment<VM: GeneralViewModel,DB: ViewDataBinding> : GeneralVMFragment<VM>(){
lateinit var iDataBinding: DB
override fun initDataBinding():View {
activityGeneralBinding = DataBindingUtil.bind(LayoutInflater.from(activity).inflate(R.layout.activity_general,null))!!
iDataBinding = DataBindingUtil.bind(LayoutInflater.from(activity).inflate(layout,null))!!
activityGeneralBinding.fl.addView(iDataBinding.root)
//TODO1
/**
* 如果使用jetpack 中的 liveData 来完成绑定,则需要使用另外一套观察者模式来接管更新,这里 databinding 的观察者模式不会通知到 livedata , 需要我们在绑定 livedata 时使用具体的 ViewDataBinding 实现来调用 ViewDataBinding.setLifecycleOwner(this); 开启。这局话可以卸载 activity 的onCreate方法里。(具体以后需要整理一份 jetpack ViewModel 资料)
* https://www.cnblogs.com/summer-xx/p/13997646.html?ivk_sa=1024320u
*/
activityGeneralBinding.lifecycleOwner = this
iDataBinding.lifecycleOwner = this
return iDataBinding.root
return activityGeneralBinding.root
}
}
\ No newline at end of file
......@@ -89,9 +89,9 @@ abstract class GeneralPagingAdapter<T:Any,V:ViewBinding>(
return Holder(LayoutInflater.from(context).inflate(layout,null))
val view = LayoutInflater.from(context).inflate(layout,null)
view.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT)
return Holder(view)
}
class Holder<V:ViewBinding>(itView: View):RecyclerView.ViewHolder(itView){
......
......@@ -6,10 +6,15 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import com.work.provide_origin.R
import com.work.provide_origin.databinding.ActivityGeneralBinding
abstract class GeneralVMFragment<VM : GeneralViewModel> : Fragment(){
lateinit var activity: Activity
protected var titleFlag: Boolean = true
lateinit var activityGeneralBinding: ActivityGeneralBinding
protected abstract var layout:Int
override fun onAttach(context: Context) {
......@@ -23,13 +28,50 @@ abstract class GeneralVMFragment<VM : GeneralViewModel> : Fragment(){
savedInstanceState: Bundle?
): View? {
var view = initDataBinding()
initDo()
createLooker()
initTitle(activityGeneralBinding.includeGeneralTitle)
initUi()
initData()
initEvent()
return view
}
protected open fun initDo(){
}
protected open fun initTitle(titleView:View){
if(titleFlag){
titleView.visibility = View.VISIBLE
titleView.findViewById<View>(R.id.free_iv).run {
setOnClickListener {
activity.finish()
}
}
titleView.findViewById<View>(R.id.finish).visibility = View.GONE
}else {
titleView.visibility = View.GONE
}
}
protected fun getLeftView():View{
return activityGeneralBinding.includeGeneralTitle.findViewById(R.id.free_iv)
}
protected fun getTitleView():TextView{
return activityGeneralBinding.includeGeneralTitle.findViewById(R.id.title)
}
protected fun setTitleNa(value:String){
activityGeneralBinding.includeGeneralTitle.findViewById<TextView>(R.id.title).run {
text = value
}
}
protected fun getRightTv(): TextView {
return activityGeneralBinding.includeGeneralTitle.findViewById<TextView>(R.id.finish)
}
abstract fun initDataBinding():View
abstract fun createLooker()
abstract fun initUi()
......
package com.work.provide_origin.util
object ProviderModelEngine {
inline fun <reified T> provider(typeKey:String):T{
return Class.forName(typeKey).getConstructor()//type
.newInstance() as T//值
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<data></data>
<androidx.constraintlayout.widget.ConstraintLayout
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">
<!-- wrap_content-->
......@@ -12,7 +12,7 @@
android:id="@+id/include_general_title"
layout="@layout/general_title"
android:layout_width="0dp"
android:layout_height="70dp"
android:layout_height="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
......
......@@ -3,7 +3,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="@color/color_f7f7f7">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
......@@ -11,7 +12,8 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
app:layout_constraintTop_toTopOf="parent"
>
<TextView
android:id="@+id/finish"
......@@ -39,6 +41,8 @@
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_101010"
android:textSize="19sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
......
......@@ -88,4 +88,8 @@ dependencies {
api rootProject.ext.android.paging_room
api rootProject.ext.android.auto_ui
api rootProject.ext.android.round_iv
api "com.google.code.gson:gson:2.9.0"
}
\ No newline at end of file
package com.work.provide_tool.apppri.dataro
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.work.provide_tool.app.IApp.Companion.app
import com.work.provide_tool.apppri.dataro.dao.FriendDao
import com.work.provide_tool.apppri.dataro.entity.FriendEntity
@Database(
entities = [FriendEntity::class],
version = 1,
exportSchema = false
)
//@TypeConverters(value = [TypeConverterData::class])
abstract class TalkDb :RoomDatabase(){
abstract fun getFriendDao(): FriendDao
// abstract fun getPlayDataDao():PlayerDataDao
// abstract fun getNotePVPDao():NotePVPDao
companion object{
private var talkDb: TalkDb? = null
fun get(): TalkDb {
if(talkDb == null){
synchronized(TalkDb::class.java){
if(null == talkDb){
talkDb = Room.databaseBuilder(app, TalkDb::class.java,"talk_info_data")
.build()
}
}
}
return talkDb!!
}
}
}
\ No newline at end of file
package com.work.provide_tool.apppri.dataro
import android.text.TextUtils
import androidx.room.TypeConverter
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
class TypeConverterData {
var g = Gson()
@TypeConverter
fun list2String(lt:List<String>?):String?{
return if(lt == null)"" else g.toJson(lt)
}
@TypeConverter
fun string2list(str:String?):List<String>?{
return if(TextUtils.isEmpty(str)) null else g.fromJson(str,object : TypeToken<List<String>>(){}.type)
}
// @TypeConverter
// fun list2String(lt:List<PlayerDataEntity>?):String?{
// return if(lt == null)"" else g.toJson(lt)
// }
//
// @TypeConverter
// fun string2list(str:String?):List<PlayerDataEntity>?{
// return if(TextUtils.isEmpty(str)) null else g.fromJson(str,object : TypeToken<List<PlayerDataEntity>>(){}.type)
// }
@TypeConverter
fun intArray2String(intarr:IntArray?):String?{
return if(intarr == null)"" else g.toJson(intarr)
}
@TypeConverter
fun string2IntArray(str:String?):IntArray?{
return if(TextUtils.isEmpty(str)) null else g.fromJson(str,object : TypeToken<IntArray>(){}.type)
}
}
\ No newline at end of file
package com.work.provide_tool.apppri.dataro.dao
import androidx.paging.PagingSource
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.work.provide_tool.apppri.dataro.entity.FriendEntity
@Dao
interface FriendDao {
@Insert
fun insertFriendData(notePVPDataEntity: FriendEntity)
@Update
fun updateFriendData(vararg notePVPDataEntity: FriendEntity)
@Query("SELECT * FROM friend order by fId")
fun queryFriendData(): PagingSource<Int, FriendEntity>
@Query("SELECT * FROM friend where id=:rId order by fId")
fun queryFriendDataWithLt(rId:Long):List<FriendEntity>?
@Delete
fun delFriendData(notePVPDataEntity: FriendEntity)
@Insert
fun insertAll(vararg notePVPDataEntity: FriendEntity)
}
\ No newline at end of file
package com.work.provide_tool.apppri.dataro.entity
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "friend")
data class FriendEntity (var id:Int,var na:String){
@PrimaryKey var fId :Long? = null
}
\ No newline at end of file
package com.work.provide_tool.apppri.util
var REF_KEY_TALK = "com.juling.work_onepage.ui.FriendModel"
\ No newline at end of file
......@@ -4,9 +4,11 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
fun FragmentActivity.turnPageFrag(layout:Int,fFrag:Fragment,toFrag:Fragment){
fun FragmentActivity.turnPageFrag(layout:Int,fFrag:Fragment?,toFrag:Fragment){
var ft = supportFragmentManager.beginTransaction()
ft.hide(fFrag)
fFrag?.run {
ft.hide(this)
}
if(!toFrag.isAdded){
ft.add(layout,toFrag)
}
......
......@@ -9,4 +9,8 @@
<color name="white">#FFFFFFFF</color>
<color name="red">#ff0000</color>
<color name="color_0ff0f0">#0ff0f0</color>
<color name="color_f7f7f7">#f7f7f7</color>
<color name="color_101010">#101010</color>
<color name="color_B7B6B6">#B7B6B6</color>
<color name="color_ff5959">#ff5959</color>
</resources>
\ No newline at end of file
......@@ -24,24 +24,23 @@ abstract class NavigationActivity<T:Fragment> : GeneralAgentActivity<NavigationV
override fun initUi() {
fragArray = providerFragment()
initNavigationView()
initOtherUi()
}
private fun initNavigationView(){
iDataBinding.navigationLl.run {
navigationWidgetClick = object:NavigationWidgetClick{
override fun onClick(f: Int, to: Int) {
turnPageFrag(R.id.fl, fragArray[f], fragArray[to])
turnPageFrag(R.id.fl, if (f == -1) null else fragArray[f], fragArray[to])
}
}
}
}
override fun initData() {
protected fun setPos(f:Int,to:Int){
iDataBinding.navigationLl.setPos(f,to)
}
override fun initEvent() {
}
abstract fun providerFragment():List<T>
abstract fun initOtherUi()
}
\ No newline at end of file
package com.juling.work_onepage
package com.juling.work_onepage.app
import android.app.Application
import com.work.provide_tool.app.IApp
......
package com.juling.work_onepage.paging
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.work.provide_tool.apppri.dataro.entity.FriendEntity
class FriendDataSou : PagingSource<Int,FriendEntity>(){
override fun getRefreshKey(state: PagingState<Int, FriendEntity>): Int? {
return null
}
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, FriendEntity> {
return LoadResult.Page(
data = arrayListOf(),//TODO1
nextKey = null,
prevKey = null
)
}
}
\ No newline at end of file
package com.juling.work_onepage.paging
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingSource
import com.work.provide_tool.apppri.dataro.TalkDb
object FriendRepository {
private val pageSz= 5
private var pagingConfig = PagingConfig(
pageSize = pageSz,// 每页显示的数据的大小
prefetchDistance = pageSz,// 预刷新的距离,距离最后一个 item 多远时加载数据
enablePlaceholders = true,//定义如果PagingSource提供了空占位符,则PagingData是否可以显示空占位符。
initialLoadSize = pageSz + pageSz + pageSz// 初始化加载数
,jumpThreshold = PagingSource.LoadResult.Page.COUNT_UNDEFINED//预取距离,定义访问必须离已加载内容的边缘多远才能触发进一步加载。
)
fun getFriendList() = Pager(pagingConfig){
TalkDb.get().getFriendDao().queryFriendData()
}.flow
}
\ No newline at end of file
package com.juling.work_onepage.ui
import android.content.Context
import androidx.recyclerview.widget.DiffUtil
import com.juling.work_onepage.R
import com.juling.work_onepage.databinding.FriendWidgetBinding
import com.work.provide_origin.origin.GeneralPagingAdapter
import com.work.provide_tool.apppri.dataro.entity.FriendEntity
import com.work.provide_tool.util.glideLoadRound
class FriendAdapter(context: Context) :GeneralPagingAdapter<FriendEntity,FriendWidgetBinding>(context,object :DiffUtil.ItemCallback<FriendEntity>(){
override fun areItemsTheSame(oldItem: FriendEntity, newItem: FriendEntity): Boolean {
return false
}
override fun areContentsTheSame(oldItem: FriendEntity, newItem: FriendEntity): Boolean {
return false
}
}){
override var layout: Int
get() = R.layout.friend_widget
set(value) {}
override fun onBindViewHolderWork(
holder: Holder<FriendWidgetBinding>,
t: FriendEntity?,
position: Int
) {
holder.rootViewType?.run {
glideLoadRound(R.mipmap.t1,uIv)
nikNa.text = "hello"
talkDetail.text = "干哈呢"
atWhat.text = "刚"
infoNu.text = "10"
}
}
}
\ No newline at end of file
package com.juling.work_onepage.ui
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.SimpleItemAnimator
import com.juling.work_onepage.R
import com.juling.work_onepage.databinding.FragmentTalkBinding
import com.work.provide_origin.origin.GeneralAgentFragment
import com.work.provide_tool.apppri.dataro.TalkDb
import com.work.provide_tool.apppri.dataro.entity.FriendEntity
import com.work.provide_tool.util.ToastUtil
import com.work.provide_tool.util.keepDataUpdateWithUi
class FriendFragment : GeneralAgentFragment<FriendViewModel, FragmentTalkBinding>() {
private lateinit var adapter:FriendAdapter
private val iViewModel by lazy {
ViewModelProvider(this)[FriendViewModel::class.java]
}
override var layout: Int
get() = R.layout.fragment_talk
set(value) {}
override fun createLooker() {
iViewModel.getFriendList().observe(this) { dt ->
keepDataUpdateWithUi(this,{
adapter.submitData(dt)
})
}
}
override fun initTitle(titleView: View) {
titleFlag = true
super.initTitle(titleView)
getLeftView().visibility = View.GONE
setTitleNa("消息")
getTitleView().setOnClickListener {
keepDataUpdateWithUi(this,{
TalkDb.get().getFriendDao().insertFriendData(FriendEntity(1,"hello"))
})
}
}
override fun initUi() {
initRv()
}
private fun initRv(){
iDataBinding.rv.run {
adapter = FriendAdapter(activity).apply {
this@FriendFragment.adapter = this
}
layoutManager = LinearLayoutManager(activity)
addItemDecoration(DividerItemDecoration(activity,DividerItemDecoration.VERTICAL).apply {
})
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
}
}
override fun initData() {
}
override fun initEvent() {
adapter.onClick = {view,t,p->
ToastUtil.show("eee")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
\ No newline at end of file
package com.juling.work_onepage.ui
import androidx.lifecycle.asLiveData
import com.juling.work_onepage.paging.FriendRepository
import com.work.provide_origin.inf.IModel
class FriendModel : IModel{
fun getFriendList() = FriendRepository.getFriendList().asLiveData()
}
\ No newline at end of file
package com.juling.work_onepage.ui
import com.work.provide_origin.origin.GeneralViewModel
import com.work.provide_origin.util.ProviderModelEngine
import com.work.provide_tool.apppri.util.REF_KEY_TALK
class FriendViewModel : GeneralViewModel(){
fun getFriendList() = ProviderModelEngine.provider<FriendModel>(REF_KEY_TALK).getFriendList()
}
\ 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="@color/color_ff5959" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<data></data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<data />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="72dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="72dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/u_iv"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_marginStart="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@mipmap/ic_launcher_round" />
<TextView
android:id="@+id/nik_na"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="9dp"
android:layout_marginTop="9dp"
android:textColor="@color/color_101010"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/u_iv"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<TextView
android:id="@+id/talk_detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="9dp"
android:textColor="@color/color_B7B6B6"
android:textSize="13sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/u_iv"
app:layout_constraintTop_toBottomOf="@+id/nik_na"
app:layout_constraintVertical_bias="0.36" />
<TextView
android:id="@+id/info_nu"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@drawable/info_nu"
android:gravity="center"
android:text="1"
android:textColor="@color/white"
android:textSize="13sp"
app:layout_constraintBottom_toBottomOf="@+id/u_iv"
app:layout_constraintEnd_toEndOf="@+id/u_iv"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="@+id/u_iv"
app:layout_constraintTop_toTopOf="@+id/u_iv"
app:layout_constraintVertical_bias="0.0" />
<TextView
android:id="@+id/at_what"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginEnd="15dp"
android:textColor="@color/color_B7B6B6"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论