이제 거의 다 왔다. 프레그먼트 패키지 몇개와 포토뷰 패키지쪽만 손보면된다.
먼저 ViewPagerActivity를 변환해보자.
1. activity_view_pager.xml 를 복사해준다.
xml에 보면 gujc.directtalk9.photoview.HackyViewPager... 부분이 있는데, 이를 처리하기위해 포토뷰 패키지에서
HackyViewPager를 복사하고 변환해준다. 그것은 아래와 같다.
위를 가지고 xml 젤 아래쪽 코드를 이와 같이 수정했다.
툴바도 androidx용 툴바로 바꾸어주었다.
그동안 변환하는 방식과 마찬가지로 이것저것 처리를 해주면
ViewPagerActivity는 아래와 같이 변환 할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.app.Activity
import android.os.Bundle
import android.util.Log
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.Glide
import com.example.fbchattingtest.R
import com.example.fbchattingtest.functionals.helpers
import java.io.File
class ViewPagerActivity: AppCompatActivity() {
companion object {
lateinit var roomID:String
lateinit var realname:String
lateinit var viewPager: ViewPager
lateinit var imgList : ArrayList<Message>
}
private val rootPath = helpers.rootPath + "/DirectTalk9/"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_view_pager)
val toolbar = findViewById(R.id.toolbar) as Toolbar
setSupportActionBar(toolbar)
roomID = getIntent().getStringExtra("roomID")
realname = getIntent().getStringExtra("realname")
viewPager = findViewById(R.id.view_pager)
viewPager.setAdapter(SamplePagerAdapter())
downloadBtn.setOnClickListener {
if (!helpers.isPermissionGranted(applicationContext as Activity, WRITE_EXTERNAL_STORAGE))
return@setOnClickListener
val message = imgList[viewPager.currentItem]
val localFile = File(rootPath, message.getFilename())
FirebaseStorage.getInstance().reference.child("files/" + message.getMsg()).getFile(localFile).addOnSuccessListener{
helpers.showMessage(applicationContext, "Downloaded file")
Log.e("DirectTalk9 ", "local file created $localFile")
}.addOnFailureListener{
Log.e("DirectTalk9 ", "local file not created $it")
}
}
val actionBar = supportActionBar
actionBar?.setTitle("PhotoView")
actionBar?.setDisplayHomeAsUpEnabled(true)
actionBar?.setHomeButtonEnabled(true)
}
override fun onOptionsItemSelected(item: MenuItem):Boolean {
return when (item.itemId) {
onBackPressed()
true
}
else -> super.onOptionsItemSelected(item)
}
}
inner class SamplePagerAdapter: PagerAdapter() {
private val storageReference: StorageReference = FirebaseStorage.getInstance().reference
private var inx = -1
init{
FirebaseFirestore.getInstance().collection("rooms").document(roomID).collection("messages").whereEqualTo("msgtype", "1")
.get()
.addOnCompleteListener{
if (!it.isSuccessful) {
return@addOnCompleteListener
}
{
val message = document.toObject(Message::class.java)
imgList.add(message)
}
}
notifyDataSetChanged()
if (inx > -1)
{
viewPager.setCurrentItem(inx)
}
}
}
override fun getCount() : Int = imgList.size
override fun instantiateItem(container:ViewGroup, position:Int):View {
val photoView = PhotoView(container.context)
.into(photoView)
container.addView(photoView, MATCH_PARENT, MATCH_PARENT)
return photoView
}
override fun destroyItem(container:ViewGroup, position:Int, `object`:Any) {
container.removeView(`object` as View)
}
override fun isViewFromObject(view:View, `object`:Any):Boolean {
return view === `object`
}
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs |
그 다음 다시 ChatActivity로 돌아와서, 아래 UserListInRoomFragment 부분을 추가해보자.
UserListinRoomFragment를 변환하다보니 필요한 것들은
아래와 같았다.
drawble에서 shape_rectangle.xml
아래는 변환한 코드 전체이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import com.bumptech.glide.Glide
import com.example.fbchattingtest.ChatModule.SelectUserActivity
import com.example.fbchattingtest.R
import java.util.ArrayList
class UserListInRoomFragment : Fragment() {
companion object {
fun getInstance(roomID: String, userModels: Map<String, UserModel>): UserListInRoomFragment {
val users = mutableListOf<UserModel>()
for ((_, value) in userModels) {users.add(value)}
val f = UserListInRoomFragment()
f.setUserList(users)
val bdl = Bundle()
bdl.putString("roomID", roomID)
f.arguments = bdl
return f
}
}
private var roomID: String? = null
private var userModels: List<UserModel>? = null
private var recyclerView: RecyclerView? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val view = inflater.inflate(R.layout.fragment_userlistinroom, container, false)
if (arguments != null) {roomID = arguments?.getString("roomID")}
recyclerView = view.findViewById(R.id.recyclerView)
recyclerView!!.layoutManager = LinearLayoutManager(inflater.context)
recyclerView!!.adapter = UserFragmentRecyclerViewAdapter()
addContactBtn.setOnClickListener {
val intent = Intent(activity, SelectUserActivity::class.java)
intent.putExtra("roomID", roomID)
startActivity(intent)
}
return view
}
fun setUserList(users: List<UserModel>) {
userModels = users
}
internal inner class UserFragmentRecyclerViewAdapter :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val storageReference: StorageReference = FirebaseStorage.getInstance().reference
private val requestOptions = RequestOptions().transforms(CenterCrop(), RoundedCorners(90))
override fun getItemCount() = userModels!!.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view =
return CustomViewHolder(view)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val user = userModels!![position]
val customViewHolder = holder as CustomViewHolder
if (user.userphoto == null) {
Glide.with(activity!!).load(R.drawable.user).apply(requestOptions).into(customViewHolder.user_photo)
} else {
Glide.with(activity!!).load(storageReference.child("userPhoto/" + user.userphoto)).apply(requestOptions).into(customViewHolder.user_photo)
}
}
}
private inner class CustomViewHolder(view: View) : RecyclerView.ViewHolder(view) {
var user_photo: ImageView = view.findViewById(R.id.user_photo)
var user_name: TextView = view.findViewById(R.id.user_name)
var user_msg: TextView = view.findViewById(R.id.user_msg)
init {
user_msg.visibility = View.GONE
}
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs |
위를 추가하고 ChatActivity에 관련 임포트를 해주면 아래와 같이 최종변환을 할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
import android.os.Bundle
import android.view.Gravity
import android.view.MenuItem
import com.example.fbchattingtest.Fragments.ChatFragment
import com.example.fbchattingtest.Fragments.UserListInRoomFragment
import com.example.fbchattingtest.R
class ChatActivity : AppCompatActivity() {
private var drawerLayout: DrawerLayout? = null
private var chatFragment: ChatFragment? = null
private var userListInRoomFragment: UserListInRoomFragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
val toolbar: Toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
val actionBar: ActionBar = supportActionBar!!
actionBar.setDisplayHomeAsUpEnabled(true)
actionBar.setHomeButtonEnabled(true)
val toUid: String = intent.getStringExtra("toUid")
val roomID: String = intent.getStringExtra("roomID")
val roomTitle: String = intent.getStringExtra("roomTitle")
actionBar.setTitle(roomTitle)
// left drawer
drawerLayout = findViewById<DrawerLayout>(R.id.drawer_layout)
rightMenuBtn.setOnClickListener(OnClickListener {
} else {
if (userListInRoomFragment == null) {
userListInRoomFragment = UserListInRoomFragment.getInstance(roomID, chatFragment!!.userList)
supportFragmentManager.beginTransaction().replace(R.id.drawerFragment, userListInRoomFragment!!).commit()
}
}
})
// chatting area
chatFragment = ChatFragment.getInstance(toUid, roomID)
supportFragmentManager.beginTransaction().replace(R.id.mainFragment, chatFragment!!).commit()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
onBackPressed()
true
}
else -> super.onOptionsItemSelected(item)
}
}
override fun onBackPressed() {
chatFragment?.backPressed()
finish()
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs |
드디어 ChatModule부분을 어느정도 완성했다. 다시 메인액티비티로 돌아와서 다시 한번 체크를 해보면, 추가가 안되있는 부분들은 아래와 같다.
먼저 R.menu 부분은 Resources부분의 메뉴 패키지를 의미하므로 기반 앱에서 복사를 해오면 된다.
그러면 action logout 부분도 추가된다.
이제 드디어 위의 Fragment들을 추가해볼때이다. 이것만 추가하면 대부분의 변환이 끝난다.
일단 UserListFragment 를 추가하면 아래와 같이 변환할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import com.bumptech.glide.Glide
import com.example.fbchattingtest.ChatModule.ChatActivity
import com.example.fbchattingtest.R
import com.example.fbchattingtest.functionals.FirestoreAdapter
class UserListFragment : Fragment() {
private var firestoreAdapter: FirestoreAdapter<*>? = null
override fun onStart() {
super.onStart()
if (firestoreAdapter != null) {
firestoreAdapter!!.startListening()
}
}
override fun onStop() {
super.onStop()
if (firestoreAdapter != null) {
firestoreAdapter!!.stopListening()
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val view = inflater.inflate(R.layout.fragment_userlist, container, false)
firestoreAdapter = RecyclerViewAdapter(FirebaseFirestore.getInstance().collection("users").orderBy("usernm"))
recyclerView.layoutManager = LinearLayoutManager(inflater.context)
recyclerView.adapter = firestoreAdapter
return view
}
inner class RecyclerViewAdapter(query: Query):FirestoreAdapter<CustomViewHolder>(query) {
private val requestOptions = RequestOptions().transforms(CenterCrop(), RoundedCorners(90))
private val storageReference: StorageReference = FirebaseStorage.getInstance().reference
private val myUid = FirebaseAuth.getInstance().currentUser!!.uid
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder = CustomViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_user, parent, false))
override fun onBindViewHolder(viewHolder: CustomViewHolder, position: Int) {
val documentSnapshot = getSnapshot(position)
val user = documentSnapshot.toObject(UserModel::class.java)
if (myUid == user!!.uid) {
viewHolder.itemView.visibility = View.INVISIBLE
return
}
viewHolder.user_msg.text = user.usermsg
if (user.userphoto == null) {
} else {
Glide.with(activity!!).load(storageReference.child("userPhoto/" + user.userphoto)).apply(requestOptions).into(viewHolder.user_photo)
}
viewHolder.itemView.setOnClickListener {
val intent = Intent(view?.context, ChatActivity::class.java)
intent.putExtra("toUid", user.uid)
startActivity(intent)
}
}
}
inner class CustomViewHolder internal constructor(view: View) : RecyclerView.ViewHolder(view) {
var user_photo: ImageView = view.findViewById(R.id.user_photo)
var user_name: TextView = view.findViewById(R.id.user_name)
var user_msg: TextView = view.findViewById(R.id.user_msg)
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">c |
아래는
ChatRoomFragment 를 변환한 것이다. 이에 관련 xml을 추가해주고... 변환한 kt 는 아래와 같다.
변환하기에 앞서 ChatRoomModel이 필요해서 이를 추가하였다.
혹시 Fragment xml에 대한 id가 찾아지지않는다면
import com.google.firebase.firestore.* 를 지워보자.
item_chatroom도 필요해서 추가하였다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
class ChatRoomFragment : Fragment() {
companion object {
fun setBadge(context: Context, count: Int) {
val launcherClassName = getLauncherClassName(context) ?: return
val intent = Intent("android.intent.action.BADGE_COUNT_UPDATE")
intent.putExtra("badge_count", count)
intent.putExtra("badge_count_package_name", context.packageName)
intent.putExtra("badge_count_class_name", launcherClassName)
context.sendBroadcast(intent)
}
fun getLauncherClassName(context: Context): String? {
val pm = context.packageManager
val intent = Intent(Intent.ACTION_MAIN)
intent.addCategory(Intent.CATEGORY_LAUNCHER)
val resolveInfos = pm.queryIntentActivities(intent, 0)
for (resolveInfo in resolveInfos) {
val pkgName = resolveInfo.activityInfo.applicationInfo.packageName
if (pkgName.equals(context.packageName, ignoreCase = true)) {
}
}
return null
}
}
@SuppressLint("SimpleDateFormat")
private val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd")
private var mAdapter: RecyclerViewAdapter? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val view: View = inflater.inflate(R.layout.fragment_chat, container, false)
recyclerView.layoutManager = LinearLayoutManager(inflater.context)
mAdapter = RecyclerViewAdapter()
recyclerView.adapter = mAdapter
simpleDateFormat.timeZone = TimeZone.getTimeZone("Asia/Seoul")
return view
}
override fun onDestroyView() {
super.onDestroyView()
if (mAdapter != null) {mAdapter!!.stopListening()}
}
// =============================================================================================
inner class RecyclerViewAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val requestOptions = RequestOptions().transforms(CenterCrop(), RoundedCorners(90))
private val roomList = ArrayList<ChatRoomModel>()
private val userList = HashMap<String, UserModel>()
private val myUid: String = FirebaseAuth.getInstance().currentUser!!.uid
private val storageReference: StorageReference = FirebaseStorage.getInstance().reference
private val firestore: FirebaseFirestore = FirebaseFirestore.getInstance()
private var listenerRegistration: ListenerRegistration? = null
private var listenerUsers: ListenerRegistration? = null
var unreadTotal: Int = 0
override fun getItemCount(): Int = roomList.size
init {
// all users information
listenerUsers = firestore.collection("users").addSnapshotListener(EventListener { value, e ->
if (e != null) { return@EventListener }
getRoomInfo()
})
}
fun getRoomInfo() {
// my chatting room information
listenerRegistration =
firestore.collection("rooms").whereGreaterThanOrEqualTo("users.$myUid", 0)
// a.orderBy("timestamp", Query.Direction.DESCENDING)
.addSnapshotListener(EventListener { value, e ->
if (e != null) { return@EventListener }
val orderedRooms =
TreeMap<Date, ChatRoomModel>(Collections.reverseOrder<Any>())
for (document in value!!) {
val message = document.toObject<Message>(Message::class.java!!)
continue
} // FieldValue.serverTimestamp is so late
val chatRoomModel = ChatRoomModel()
chatRoomModel.lastDatetime = simpleDateFormat.format(message.timestamp)
when (message.msgtype) {
"1" -> chatRoomModel.lastMsg = ("Image")
"2" -> chatRoomModel.lastMsg = ("File")
}
}
chatRoomModel.userCount = (users!!.size)
if (myUid == key) {
val unread = (users[key] as Long).toInt()
unreadTotal += unread
chatRoomModel.unreadCount = unread
break
}
}
if (myUid == key) continue
val userModel = userList[key]
chatRoomModel.photo = userModel.userphoto
}
} else { // group chat room
}
if (message.timestamp == null) message.timestamp = Date()
orderedRooms[message.timestamp] = chatRoomModel
}
for ((_, value1) in orderedRooms) {
roomList.add(value1)
}
notifyDataSetChanged()
setBadge(context!!, unreadTotal!!)
})
}
fun stopListening() {
if (listenerRegistration != null) {
listenerRegistration!!.remove()
listenerRegistration = null
}
if (listenerUsers != null) {
listenerUsers!!.remove()
listenerUsers = null
}
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view =
return RoomViewHolder(view)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val roomViewHolder = holder as RoomViewHolder
val chatRoomModel = roomList[position]
roomViewHolder.last_msg.text = chatRoomModel.lastMsg
roomViewHolder.last_time.text = chatRoomModel.lastDatetime
.apply(requestOptions)
.into(roomViewHolder.room_image)
} else {
.apply(requestOptions)
.into(roomViewHolder.room_image)
}
if (chatRoomModel.userCount!! > 2) {
roomViewHolder.room_count.visibility = View.VISIBLE
} else {
roomViewHolder.room_count.visibility = View.INVISIBLE
}
if (chatRoomModel.unreadCount!! > 0) {
roomViewHolder.unread_count.visibility = View.VISIBLE
} else {
roomViewHolder.unread_count.visibility = View.INVISIBLE
}
roomViewHolder.itemView.setOnClickListener { v ->
val intent = Intent(v.context, ChatActivity::class.java)
intent.putExtra("roomID", chatRoomModel.roomID)
intent.putExtra("roomTitle", chatRoomModel.title)
startActivity(intent)
}
}
private inner class RoomViewHolder internal constructor(view: View) :
RecyclerView.ViewHolder(view) {
var room_image: ImageView = view.findViewById(R.id.room_image)
var room_title: TextView = view.findViewById(R.id.room_title)
var last_msg: TextView = view.findViewById(R.id.last_msg)
var last_time: TextView = view.findViewById(R.id.last_time)
var room_count: TextView = view.findViewById(R.id.room_count)
var unread_count: TextView = view.findViewById(R.id.unread_count)
}
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs |