mirror of
https://github.com/nextcloud/talk-android
synced 2025-07-11 06:44:09 +01:00
add UI logic + close poll system message
add close poll button (wip/temporarily?) add "close poll" system message add UI related logic to PollMainViewModel add placeholder for pollDetails in UI Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
parent
ea0b7d07cc
commit
b504af1cd9
@ -491,7 +491,8 @@ data class ChatMessage(
|
|||||||
REACTION,
|
REACTION,
|
||||||
REACTION_DELETED,
|
REACTION_DELETED,
|
||||||
REACTION_REVOKED,
|
REACTION_REVOKED,
|
||||||
POLL_VOTED
|
POLL_VOTED,
|
||||||
|
POLL_CLOSED
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -65,6 +65,7 @@ import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.MODERAT
|
|||||||
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.OBJECT_SHARED
|
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.OBJECT_SHARED
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.PASSWORD_REMOVED
|
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.PASSWORD_REMOVED
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.PASSWORD_SET
|
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.PASSWORD_SET
|
||||||
|
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.POLL_CLOSED
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.POLL_VOTED
|
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.POLL_VOTED
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.REACTION
|
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.REACTION
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.REACTION_DELETED
|
import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.REACTION_DELETED
|
||||||
@ -169,6 +170,7 @@ class EnumSystemMessageTypeConverter : StringBasedTypeConverter<ChatMessage.Syst
|
|||||||
"reaction_deleted" -> REACTION_DELETED
|
"reaction_deleted" -> REACTION_DELETED
|
||||||
"reaction_revoked" -> REACTION_REVOKED
|
"reaction_revoked" -> REACTION_REVOKED
|
||||||
"poll_voted" -> POLL_VOTED
|
"poll_voted" -> POLL_VOTED
|
||||||
|
"poll_closed" -> POLL_CLOSED
|
||||||
else -> DUMMY
|
else -> DUMMY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,6 +229,7 @@ class EnumSystemMessageTypeConverter : StringBasedTypeConverter<ChatMessage.Syst
|
|||||||
REACTION_DELETED -> return "reaction_deleted"
|
REACTION_DELETED -> return "reaction_deleted"
|
||||||
REACTION_REVOKED -> return "reaction_revoked"
|
REACTION_REVOKED -> return "reaction_revoked"
|
||||||
POLL_VOTED -> return "poll_voted"
|
POLL_VOTED -> return "poll_voted"
|
||||||
|
POLL_CLOSED -> return "poll_closed"
|
||||||
else -> return ""
|
else -> return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package com.nextcloud.talk.polls.adapters
|
package com.nextcloud.talk.polls.adapters
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.view.View
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nextcloud.talk.databinding.PollResultItemBinding
|
import com.nextcloud.talk.databinding.PollResultItemBinding
|
||||||
|
|
||||||
class PollResultViewHolder(
|
class PollResultViewHolder(
|
||||||
private val binding: PollResultItemBinding
|
private val binding: PollResultItemBinding,
|
||||||
|
private val showDetails: Boolean
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
@ -14,5 +16,11 @@ class PollResultViewHolder(
|
|||||||
binding.pollOptionText.text = pollResultItem.pollOption
|
binding.pollOptionText.text = pollResultItem.pollOption
|
||||||
binding.pollOptionPercentText.text = pollResultItem.pollPercent.toString() + "%"
|
binding.pollOptionPercentText.text = pollResultItem.pollPercent.toString() + "%"
|
||||||
binding.pollOptionBar.progress = pollResultItem.pollPercent
|
binding.pollOptionBar.progress = pollResultItem.pollPercent
|
||||||
|
|
||||||
|
if (showDetails) {
|
||||||
|
binding.pollOptionDetail.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.pollOptionDetail.visibility = View.GONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,14 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
import com.nextcloud.talk.databinding.PollResultItemBinding
|
import com.nextcloud.talk.databinding.PollResultItemBinding
|
||||||
|
|
||||||
class PollResultsAdapter(
|
class PollResultsAdapter(
|
||||||
private val clickListener: PollResultItemClickListener
|
private val clickListener: PollResultItemClickListener,
|
||||||
|
private val showDetails: Boolean
|
||||||
) : RecyclerView.Adapter<PollResultViewHolder>() {
|
) : RecyclerView.Adapter<PollResultViewHolder>() {
|
||||||
internal var list: MutableList<PollResultItem> = ArrayList<PollResultItem>()
|
internal var list: MutableList<PollResultItem> = ArrayList<PollResultItem>()
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PollResultViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PollResultViewHolder {
|
||||||
val itemBinding = PollResultItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
val itemBinding = PollResultItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
return PollResultViewHolder(itemBinding)
|
return PollResultViewHolder(itemBinding, showDetails)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: PollResultViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: PollResultViewHolder, position: Int) {
|
||||||
|
@ -5,10 +5,6 @@ import io.reactivex.Observable
|
|||||||
|
|
||||||
interface PollRepository {
|
interface PollRepository {
|
||||||
|
|
||||||
fun getPoll(roomToken: String, pollId: String): Observable<Poll>?
|
|
||||||
|
|
||||||
fun vote(roomToken: String, pollId: String, option: Int): Observable<Poll>?
|
|
||||||
|
|
||||||
fun createPoll(
|
fun createPoll(
|
||||||
roomToken: String,
|
roomToken: String,
|
||||||
question: String,
|
question: String,
|
||||||
@ -16,4 +12,10 @@ interface PollRepository {
|
|||||||
resultMode: Int,
|
resultMode: Int,
|
||||||
maxVotes: Int
|
maxVotes: Int
|
||||||
): Observable<Poll>?
|
): Observable<Poll>?
|
||||||
|
|
||||||
|
fun getPoll(roomToken: String, pollId: String): Observable<Poll>?
|
||||||
|
|
||||||
|
fun vote(roomToken: String, pollId: String, option: Int): Observable<Poll>?
|
||||||
|
|
||||||
|
fun closePoll(roomToken: String, pollId: String): Observable<Poll>?
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,18 @@ class PollRepositoryImpl(private val ncApi: NcApi, private val currentUserProvid
|
|||||||
).map { mapToPoll(it.ocs?.data!!) }
|
).map { mapToPoll(it.ocs?.data!!) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun closePoll(roomToken: String, pollId: String): Observable<Poll> {
|
||||||
|
|
||||||
|
return ncApi.closePoll(
|
||||||
|
credentials,
|
||||||
|
ApiUtils.getUrlForPoll(
|
||||||
|
currentUserProvider.currentUser?.baseUrl,
|
||||||
|
roomToken,
|
||||||
|
pollId
|
||||||
|
),
|
||||||
|
).map { mapToPoll(it.ocs?.data!!) }
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private fun mapToPoll(pollResponse: PollResponse): Poll {
|
private fun mapToPoll(pollResponse: PollResponse): Poll {
|
||||||
|
@ -60,7 +60,7 @@ class PollMainDialogFragment(
|
|||||||
when (state) {
|
when (state) {
|
||||||
PollMainViewModel.InitialState -> {}
|
PollMainViewModel.InitialState -> {}
|
||||||
|
|
||||||
is PollMainViewModel.PollVotedState -> {
|
is PollMainViewModel.PollResultState -> {
|
||||||
if (state.poll.resultMode == Poll.RESULT_MODE_HIDDEN) {
|
if (state.poll.resultMode == Poll.RESULT_MODE_HIDDEN) {
|
||||||
showVoteFragment()
|
showVoteFragment()
|
||||||
} else {
|
} else {
|
||||||
@ -68,7 +68,7 @@ class PollMainDialogFragment(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is PollMainViewModel.PollUnvotedState -> {
|
is PollMainViewModel.PollVoteState -> {
|
||||||
if (state.poll.status == Poll.STATUS_CLOSED) {
|
if (state.poll.status == Poll.STATUS_CLOSED) {
|
||||||
showResultsFragment()
|
showResultsFragment()
|
||||||
} else {
|
} else {
|
||||||
|
@ -77,26 +77,23 @@ class PollResultsFragment(
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
adapter = PollResultsAdapter(this)
|
|
||||||
_binding?.pollResultsList?.adapter = adapter
|
|
||||||
_binding?.pollResultsList?.layoutManager = LinearLayoutManager(context)
|
|
||||||
|
|
||||||
parentViewModel.viewState.observe(viewLifecycleOwner) { state ->
|
parentViewModel.viewState.observe(viewLifecycleOwner) { state ->
|
||||||
if (state is PollMainViewModel.PollVotedState &&
|
if (state is PollMainViewModel.PollResultState) {
|
||||||
state.poll.resultMode == Poll.RESULT_MODE_PUBLIC
|
initAdapter(state.showDetails)
|
||||||
) {
|
|
||||||
|
|
||||||
initPollResults(state.poll)
|
initPollResults(state.poll)
|
||||||
initAmountVotersInfo(state)
|
initAmountVotersInfo(state)
|
||||||
initEditButton(state)
|
initEditButton(state.showEditButton)
|
||||||
} else if (state is PollMainViewModel.PollUnvotedState &&
|
initCloseButton(state.showCloseButton)
|
||||||
state.poll.status == Poll.STATUS_CLOSED
|
|
||||||
) {
|
|
||||||
Log.d(TAG, "show results also if self never voted")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initAdapter(showDetails: Boolean) {
|
||||||
|
adapter = PollResultsAdapter(this, showDetails)
|
||||||
|
_binding?.pollResultsList?.adapter = adapter
|
||||||
|
_binding?.pollResultsList?.layoutManager = LinearLayoutManager(context)
|
||||||
|
}
|
||||||
|
|
||||||
private fun initPollResults(poll: Poll) {
|
private fun initPollResults(poll: Poll) {
|
||||||
if (poll.details != null) {
|
if (poll.details != null) {
|
||||||
val votersAmount = poll.details.size
|
val votersAmount = poll.details.size
|
||||||
@ -128,15 +125,26 @@ class PollResultsFragment(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initAmountVotersInfo(state: PollMainViewModel.PollVotedState) {
|
private fun initAmountVotersInfo(state: PollMainViewModel.PollResultState) {
|
||||||
_binding?.pollAmountVoters?.text = String.format(
|
_binding?.pollAmountVoters?.text = String.format(
|
||||||
resources.getString(R.string.polls_amount_voters),
|
resources.getString(R.string.polls_amount_voters),
|
||||||
state.poll.numVoters
|
state.poll.numVoters
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initEditButton(state: PollMainViewModel.PollVotedState) {
|
// private fun initEditButton(state: PollMainViewModel.PollResultState) {
|
||||||
if (state.poll.status == Poll.STATUS_OPEN && state.poll.resultMode == Poll.RESULT_MODE_PUBLIC) {
|
// if (state.poll.status == Poll.STATUS_OPEN && state.poll.resultMode == Poll.RESULT_MODE_PUBLIC) {
|
||||||
|
// _binding?.editVoteButton?.visibility = View.VISIBLE
|
||||||
|
// _binding?.editVoteButton?.setOnClickListener {
|
||||||
|
// parentViewModel.edit()
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// _binding?.editVoteButton?.visibility = View.GONE
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
private fun initEditButton(showEditButton: Boolean) {
|
||||||
|
if (showEditButton) {
|
||||||
_binding?.editVoteButton?.visibility = View.VISIBLE
|
_binding?.editVoteButton?.visibility = View.VISIBLE
|
||||||
_binding?.editVoteButton?.setOnClickListener {
|
_binding?.editVoteButton?.setOnClickListener {
|
||||||
parentViewModel.edit()
|
parentViewModel.edit()
|
||||||
@ -146,6 +154,17 @@ class PollResultsFragment(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initCloseButton(showCloseButton: Boolean) {
|
||||||
|
if (showCloseButton) {
|
||||||
|
_binding?.closeVoteButton?.visibility = View.VISIBLE
|
||||||
|
_binding?.closeVoteButton?.setOnClickListener {
|
||||||
|
parentViewModel.closePoll()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_binding?.closeVoteButton?.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onClick(pollResultItem: PollResultItem) {
|
override fun onClick(pollResultItem: PollResultItem) {
|
||||||
Log.d(TAG, "click..")
|
Log.d(TAG, "click..")
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ class PollVoteFragment(
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
parentViewModel.viewState.observe(viewLifecycleOwner) { state ->
|
parentViewModel.viewState.observe(viewLifecycleOwner) { state ->
|
||||||
if (state is PollMainViewModel.PollUnvotedState) {
|
if (state is PollMainViewModel.PollVoteState) {
|
||||||
val poll = state.poll
|
val poll = state.poll
|
||||||
binding.radioGroup.removeAllViews()
|
binding.radioGroup.removeAllViews()
|
||||||
poll.options?.map { option ->
|
poll.options?.map { option ->
|
||||||
@ -80,7 +80,7 @@ class PollVoteFragment(
|
|||||||
radioButton.id = index
|
radioButton.id = index
|
||||||
binding.radioGroup.addView(radioButton)
|
binding.radioGroup.addView(radioButton)
|
||||||
}
|
}
|
||||||
} else if (state is PollMainViewModel.PollVotedState && state.poll.resultMode == Poll.RESULT_MODE_HIDDEN) {
|
} else if (state is PollMainViewModel.PollResultState && state.poll.resultMode == Poll.RESULT_MODE_HIDDEN) {
|
||||||
Log.d(TAG, "show vote screen also for resultMode hidden poll when already voted")
|
Log.d(TAG, "show vote screen also for resultMode hidden poll when already voted")
|
||||||
// TODO: other text for submit button
|
// TODO: other text for submit button
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import androidx.lifecycle.MutableLiveData
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import com.nextcloud.talk.polls.model.Poll
|
import com.nextcloud.talk.polls.model.Poll
|
||||||
import com.nextcloud.talk.polls.repositories.PollRepository
|
import com.nextcloud.talk.polls.repositories.PollRepository
|
||||||
|
import com.nextcloud.talk.utils.database.user.UserUtils
|
||||||
import io.reactivex.Observer
|
import io.reactivex.Observer
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
@ -25,6 +26,9 @@ import javax.inject.Inject
|
|||||||
*/
|
*/
|
||||||
class PollMainViewModel @Inject constructor(private val repository: PollRepository) : ViewModel() {
|
class PollMainViewModel @Inject constructor(private val repository: PollRepository) : ViewModel() {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var userUtils: UserUtils
|
||||||
|
|
||||||
private lateinit var roomToken: String
|
private lateinit var roomToken: String
|
||||||
private lateinit var pollId: String
|
private lateinit var pollId: String
|
||||||
|
|
||||||
@ -32,8 +36,13 @@ class PollMainViewModel @Inject constructor(private val repository: PollReposito
|
|||||||
|
|
||||||
sealed interface ViewState
|
sealed interface ViewState
|
||||||
object InitialState : ViewState
|
object InitialState : ViewState
|
||||||
open class PollUnvotedState(val poll: Poll) : ViewState
|
open class PollVoteState(val poll: Poll) : ViewState
|
||||||
open class PollVotedState(val poll: Poll) : ViewState
|
open class PollResultState(
|
||||||
|
val poll: Poll,
|
||||||
|
val showDetails: Boolean,
|
||||||
|
val showEditButton: Boolean,
|
||||||
|
val showCloseButton: Boolean
|
||||||
|
) : ViewState
|
||||||
|
|
||||||
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
|
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
|
||||||
val viewState: LiveData<ViewState>
|
val viewState: LiveData<ViewState>
|
||||||
@ -65,6 +74,14 @@ class PollMainViewModel @Inject constructor(private val repository: PollReposito
|
|||||||
?.subscribe(PollObserver())
|
?.subscribe(PollObserver())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun closePoll() {
|
||||||
|
repository.closePoll(roomToken, pollId)
|
||||||
|
?.doOnSubscribe { disposable = it }
|
||||||
|
?.subscribeOn(Schedulers.io())
|
||||||
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
?.subscribe(PollObserver())
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
super.onCleared()
|
super.onCleared()
|
||||||
disposable?.dispose()
|
disposable?.dispose()
|
||||||
@ -86,16 +103,24 @@ class PollMainViewModel @Inject constructor(private val repository: PollReposito
|
|||||||
|
|
||||||
override fun onComplete() {
|
override fun onComplete() {
|
||||||
if (editPoll) {
|
if (editPoll) {
|
||||||
_viewState.value = PollUnvotedState(poll)
|
_viewState.value = PollVoteState(poll)
|
||||||
editPoll = false
|
editPoll = false
|
||||||
} else if (poll.votedSelf.isNullOrEmpty()) {
|
} else if (poll.votedSelf.isNullOrEmpty()) {
|
||||||
_viewState.value = PollUnvotedState(poll)
|
_viewState.value = PollVoteState(poll)
|
||||||
} else {
|
} else {
|
||||||
_viewState.value = PollVotedState(poll)
|
val showEditButton = poll.status == Poll.STATUS_OPEN && poll.resultMode == Poll.RESULT_MODE_PUBLIC
|
||||||
|
val showDetails = poll.status == Poll.STATUS_CLOSED && poll.resultMode == Poll.RESULT_MODE_PUBLIC
|
||||||
|
val showCloseButton = poll.status == Poll.STATUS_OPEN && isPollCreatedByCurrentUser(poll)
|
||||||
|
|
||||||
|
_viewState.value = PollResultState(poll, showDetails, showEditButton, showCloseButton)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isPollCreatedByCurrentUser(poll: Poll): Boolean {
|
||||||
|
return userUtils.currentUser?.userId == poll.actorId
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = PollMainViewModel::class.java.simpleName
|
private val TAG = PollMainViewModel::class.java.simpleName
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,18 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@+id/poll_results_list_wrapper"
|
app:layout_constraintTop_toBottomOf="@+id/poll_results_list_wrapper"
|
||||||
tools:text="Poll results - 93 votes" />
|
tools:text="Poll results - 93 votes" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/close_vote_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="Close"
|
||||||
|
android:theme="@style/Button.Primary"
|
||||||
|
app:cornerRadius="@dimen/button_corner_radius"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/edit_vote_button"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/poll_results_list_wrapper" />
|
||||||
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/edit_vote_button"
|
android:id="@+id/edit_vote_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -30,4 +30,19 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@+id/poll_option_text"
|
app:layout_constraintTop_toBottomOf="@+id/poll_option_text"
|
||||||
style="?android:attr/progressBarStyleHorizontal" />
|
style="?android:attr/progressBarStyleHorizontal" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/poll_option_detail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/poll_option_text"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/poll_option_bar">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="here the details..." />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
Loading…
Reference in New Issue
Block a user