mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-31 13:48:20 +01:00
[Messages] Add new attachments view. Allow replying to deleted messages.
This commit is contained in:
parent
0e4d609bbf
commit
8a4866cb62
@ -5,28 +5,16 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.modules.messages
|
package pl.szczodrzynski.edziennik.ui.modules.messages
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
import android.text.TextUtils
|
|
||||||
import android.view.Gravity.CENTER_VERTICAL
|
|
||||||
import android.view.Gravity.END
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.FrameLayout
|
|
||||||
import android.widget.ProgressBar
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.widget.PopupMenu
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import com.google.android.material.chip.Chip
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.mikepenz.iconics.IconicsColor
|
|
||||||
import com.mikepenz.iconics.IconicsDrawable
|
import com.mikepenz.iconics.IconicsDrawable
|
||||||
import com.mikepenz.iconics.IconicsSize
|
|
||||||
import com.mikepenz.iconics.typeface.IIcon
|
|
||||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||||
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont
|
|
||||||
import com.mikepenz.iconics.utils.sizeDp
|
import com.mikepenz.iconics.utils.sizeDp
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
@ -34,9 +22,6 @@ import org.greenrobot.eventbus.Subscribe
|
|||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent.Companion.TYPE_FINISHED
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent.Companion.TYPE_PROGRESS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore.Companion.LOGIN_TYPE_IDZIENNIK
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore.Companion.LOGIN_TYPE_IDZIENNIK
|
||||||
@ -47,14 +32,9 @@ import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|||||||
import pl.szczodrzynski.edziennik.databinding.MessageFragmentBinding
|
import pl.szczodrzynski.edziennik.databinding.MessageFragmentBinding
|
||||||
import pl.szczodrzynski.edziennik.utils.Anim
|
import pl.szczodrzynski.edziennik.utils.Anim
|
||||||
import pl.szczodrzynski.edziennik.utils.BetterLink
|
import pl.szczodrzynski.edziennik.utils.BetterLink
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.getStringFromFile
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.readableFileSize
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
import pl.szczodrzynski.navlib.colorAttr
|
import pl.szczodrzynski.navlib.colorAttr
|
||||||
import java.io.File
|
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@ -72,7 +52,6 @@ class MessageFragment : Fragment(), CoroutineScope {
|
|||||||
get() = job + Dispatchers.Main
|
get() = job + Dispatchers.Main
|
||||||
|
|
||||||
private lateinit var message: MessageFull
|
private lateinit var message: MessageFull
|
||||||
private var attachmentList = mutableListOf<Attachment>()
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
activity = (getActivity() as MainActivity?) ?: return null
|
activity = (getActivity() as MainActivity?) ?: return null
|
||||||
@ -238,9 +217,9 @@ class MessageFragment : Fragment(), CoroutineScope {
|
|||||||
|
|
||||||
b.subject.text = message.subject
|
b.subject.text = message.subject
|
||||||
|
|
||||||
b.replyButton.isVisible = message.type == TYPE_RECEIVED
|
b.replyButton.isVisible = message.type == TYPE_RECEIVED || message.type == TYPE_DELETED
|
||||||
b.deleteButton.isVisible = message.type == TYPE_RECEIVED
|
b.deleteButton.isVisible = message.type == TYPE_RECEIVED
|
||||||
if (message.type == TYPE_RECEIVED) {
|
if (message.type == TYPE_RECEIVED || message.type == TYPE_DELETED) {
|
||||||
activity.navView.apply {
|
activity.navView.apply {
|
||||||
bottomBar.apply {
|
bottomBar.apply {
|
||||||
fabEnable = true
|
fabEnable = true
|
||||||
@ -291,173 +270,21 @@ class MessageFragment : Fragment(), CoroutineScope {
|
|||||||
MessagesFragment.pageSelection = min(message.type, 1)
|
MessagesFragment.pageSelection = min(message.type, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val attachmentOnClick = { v: View ->
|
|
||||||
if (v.tag is Int) {
|
|
||||||
downloadAttachment(v.tag as Int)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val attachmentOnLongClick = { v: View ->
|
|
||||||
(v.tag as? Int)?.let { tag ->
|
|
||||||
val popupMenu = PopupMenu(v.context, v)
|
|
||||||
popupMenu.menu.add(0, tag, 0, R.string.messages_attachment_download_again)
|
|
||||||
popupMenu.setOnMenuItemClickListener {
|
|
||||||
downloadAttachment(it.itemId, forceDownload = true)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
popupMenu.show()
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showAttachments() {
|
private fun showAttachments() {
|
||||||
if (message.attachmentIds != null) {
|
if (message.attachmentIds.isNullOrEmpty() || message.attachmentNames.isNullOrEmpty()) {
|
||||||
val insertPoint = b.attachments
|
b.attachmentsTitle.isVisible = false
|
||||||
insertPoint.removeAllViews()
|
b.attachmentsFragment.isVisible = false
|
||||||
|
|
||||||
val chipLayoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
|
||||||
chipLayoutParams.setMargins(0, 8.dp, 0, 0)
|
|
||||||
|
|
||||||
val progressLayoutParams = FrameLayout.LayoutParams(18.dp, 18.dp)
|
|
||||||
progressLayoutParams.setMargins(8.dp, 0, 8.dp, 0)
|
|
||||||
progressLayoutParams.gravity = END or CENTER_VERTICAL
|
|
||||||
|
|
||||||
// CREATE VIEWS AND AN OBJECT FOR EVERY ATTACHMENT
|
|
||||||
|
|
||||||
message.attachmentNames?.forEachIndexed { index, name ->
|
|
||||||
val messageId = message.id
|
|
||||||
val id = message.attachmentIds?.getOrNull(index) ?: return@forEachIndexed
|
|
||||||
val size = message.attachmentSizes?.getOrNull(index) ?: return@forEachIndexed
|
|
||||||
// create the parent
|
|
||||||
val attachmentLayout = FrameLayout(b.root.context)
|
|
||||||
attachmentLayout.setPadding(16.dp, 0, 16.dp, 0)
|
|
||||||
|
|
||||||
val attachmentChip = Chip(attachmentLayout.context)
|
|
||||||
//attachmentChip.setChipBackgroundColorResource(ThemeUtils.getChipColorRes());
|
|
||||||
attachmentChip.layoutParams = chipLayoutParams
|
|
||||||
attachmentChip.chipMinHeight = 40.dp.toFloat()
|
|
||||||
//attachmentChip.height = Utils.dpToPx(40)
|
|
||||||
|
|
||||||
// show the file size or not
|
|
||||||
if (size == -1L)
|
|
||||||
attachmentChip.text = getString(R.string.messages_attachment_no_size_format, name)
|
|
||||||
else
|
|
||||||
attachmentChip.text = getString(R.string.messages_attachment_format, name, readableFileSize(size))
|
|
||||||
attachmentChip.ellipsize = TextUtils.TruncateAt.MIDDLE
|
|
||||||
|
|
||||||
// create an icon for the attachment
|
|
||||||
val icon: IIcon = when (Utils.getExtensionFromFileName(name)) {
|
|
||||||
"doc", "docx", "odt", "rtf" -> SzkolnyFont.Icon.szf_file_word_outline
|
|
||||||
"xls", "xlsx", "ods" -> SzkolnyFont.Icon.szf_file_excel_outline
|
|
||||||
"ppt", "pptx", "odp" -> SzkolnyFont.Icon.szf_file_powerpoint_outline
|
|
||||||
"pdf" -> SzkolnyFont.Icon.szf_file_pdf_outline
|
|
||||||
"mp3", "wav", "aac" -> SzkolnyFont.Icon.szf_file_music_outline
|
|
||||||
"mp4", "avi", "3gp", "mkv", "flv" -> SzkolnyFont.Icon.szf_file_video_outline
|
|
||||||
"jpg", "jpeg", "png", "bmp", "gif" -> SzkolnyFont.Icon.szf_file_image_outline
|
|
||||||
"zip", "rar", "tar", "7z" -> SzkolnyFont.Icon.szf_zip_box_outline
|
|
||||||
"html", "cpp", "c", "h", "css", "java", "py" -> SzkolnyFont.Icon.szf_file_code_outline
|
|
||||||
else -> CommunityMaterial.Icon.cmd_file_document_outline
|
|
||||||
}
|
|
||||||
attachmentChip.chipIcon = IconicsDrawable(activity).color(IconicsColor.colorRes(R.color.colorPrimary)).icon(icon).size(IconicsSize.dp(26))
|
|
||||||
attachmentChip.closeIcon = IconicsDrawable(activity).icon(CommunityMaterial.Icon.cmd_check).size(IconicsSize.dp(18)).color(IconicsColor.colorInt(Utils.getAttr(activity, android.R.attr.textColorPrimary)))
|
|
||||||
attachmentChip.isCloseIconVisible = false
|
|
||||||
// set the object's index in the attachmentList as the tag
|
|
||||||
attachmentChip.tag = index
|
|
||||||
attachmentChip.onClick(attachmentOnClick)
|
|
||||||
attachmentChip.onLongClick(attachmentOnLongClick)
|
|
||||||
attachmentLayout.addView(attachmentChip)
|
|
||||||
|
|
||||||
val attachmentProgress = ProgressBar(attachmentLayout.context)
|
|
||||||
attachmentProgress.layoutParams = progressLayoutParams
|
|
||||||
attachmentProgress.visibility = View.GONE
|
|
||||||
attachmentLayout.addView(attachmentProgress)
|
|
||||||
|
|
||||||
insertPoint.addView(attachmentLayout)
|
|
||||||
// create an object and add to the list
|
|
||||||
val a = Attachment(App.profileId, messageId, id, name, size, attachmentLayout, attachmentChip, attachmentProgress)
|
|
||||||
attachmentList.add(a)
|
|
||||||
// check if the file is already downloaded. Show the check icon if necessary and set `downloaded` to true.
|
|
||||||
checkAttachment(a)
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// no attachments found
|
|
||||||
b.attachmentsTitle.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun downloadAttachment(index: Int, forceDownload: Boolean = false) {
|
|
||||||
val attachment = attachmentList[index]
|
|
||||||
|
|
||||||
if (!forceDownload && attachment.downloaded != null) {
|
|
||||||
Utils.openFile(activity, File(attachment.downloaded))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
attachment.chip.isEnabled = false
|
|
||||||
attachment.chip.setTextColor(Themes.getSecondaryTextColor(activity))
|
|
||||||
attachment.progressBar.visibility = View.VISIBLE
|
|
||||||
|
|
||||||
EdziennikTask.attachmentGet(
|
|
||||||
App.profileId,
|
|
||||||
message,
|
|
||||||
attachment.attachmentId,
|
|
||||||
attachment.attachmentName
|
|
||||||
).enqueue(activity)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
|
||||||
fun onAttachmentGetEvent(event: AttachmentGetEvent) {
|
|
||||||
EventBus.getDefault().removeStickyEvent(event)
|
|
||||||
attachmentList.firstOrNull { it.profileId == event.profileId
|
|
||||||
&& it.messageId == event.ownerId
|
|
||||||
&& it.attachmentId == event.attachmentId }?.let { attachment ->
|
|
||||||
|
|
||||||
when (event.eventType) {
|
|
||||||
TYPE_FINISHED -> {
|
|
||||||
// save the downloaded file name
|
|
||||||
attachment.downloaded = event.fileName
|
|
||||||
|
|
||||||
// set the correct name (and size)
|
|
||||||
if (attachment.attachmentSize == -1L)
|
|
||||||
attachment.chip.text = getString(R.string.messages_attachment_no_size_format, attachment.attachmentName)
|
|
||||||
else
|
|
||||||
attachment.chip.text = getString(R.string.messages_attachment_format, attachment.attachmentName, readableFileSize(attachment.attachmentSize))
|
|
||||||
|
|
||||||
// hide the progress bar and show a tick icon
|
|
||||||
attachment.progressBar.visibility = View.GONE
|
|
||||||
attachment.chip.isEnabled = true
|
|
||||||
attachment.chip.setTextColor(Themes.getPrimaryTextColor(activity))
|
|
||||||
attachment.chip.isCloseIconVisible = true
|
|
||||||
|
|
||||||
// open the file
|
|
||||||
Utils.openFile(activity, File(attachment.downloaded))
|
|
||||||
}
|
|
||||||
|
|
||||||
TYPE_PROGRESS -> {
|
|
||||||
attachment.chip.text = getString(R.string.messages_attachment_downloading_format, attachment.attachmentName, event.bytesWritten.toFloat() / 1000000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkAttachment(attachment: Attachment) {
|
|
||||||
val storageDir = Environment.getExternalStoragePublicDirectory("Szkolny.eu")
|
|
||||||
storageDir.mkdirs()
|
|
||||||
|
|
||||||
val attachmentDataFile = File(storageDir, "." + attachment.profileId + "_" + attachment.messageId + "_" + attachment.attachmentId)
|
|
||||||
if (attachmentDataFile.exists()) {
|
|
||||||
try {
|
|
||||||
val attachmentFileName = getStringFromFile(attachmentDataFile)
|
|
||||||
val attachmentFile = File(attachmentFileName)
|
|
||||||
if (attachmentFile.exists()) {
|
|
||||||
attachment.downloaded = attachmentFileName
|
|
||||||
attachment.chip.isCloseIconVisible = true
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
//app.apiEdziennik.guiReportException(activity, 355, e)
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
b.attachmentsTitle.isVisible = true
|
||||||
|
b.attachmentsFragment.isVisible = true
|
||||||
|
b.attachmentsFragment.init(Bundle().also {
|
||||||
|
it.putInt("profileId", message.profileId)
|
||||||
|
it.putLongArray("attachmentIds", message.attachmentIds!!.toLongArray())
|
||||||
|
it.putStringArray("attachmentNames", message.attachmentNames!!.toTypedArray())
|
||||||
|
//if (message.attachmentSizes.isNotNullNorEmpty())
|
||||||
|
// it.putLongArray("attachmentSizes", message.attachmentSizes!!.toLongArray())
|
||||||
|
}, owner = message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,20 +300,4 @@ class MessageFragment : Fragment(), CoroutineScope {
|
|||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Attachment(
|
|
||||||
var profileId: Int,
|
|
||||||
var messageId: Long,
|
|
||||||
var attachmentId: Long,
|
|
||||||
var attachmentName: String,
|
|
||||||
var attachmentSize: Long,
|
|
||||||
var parent: FrameLayout,
|
|
||||||
var chip: Chip,
|
|
||||||
var progressBar: ProgressBar
|
|
||||||
) {
|
|
||||||
/**
|
|
||||||
* An absolute path of the downloaded file. `null` if not downloaded yet.
|
|
||||||
*/
|
|
||||||
internal var downloaded: String? = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ class MessagesListFragment : LazyFragment(), CoroutineScope {
|
|||||||
(b.list.layoutManager as? LinearLayoutManager)?.let { layoutManager ->
|
(b.list.layoutManager as? LinearLayoutManager)?.let { layoutManager ->
|
||||||
if (topPosition != NO_POSITION && topPosition > layoutManager.findLastCompletelyVisibleItemPosition()) {
|
if (topPosition != NO_POSITION && topPosition > layoutManager.findLastCompletelyVisibleItemPosition()) {
|
||||||
b.list.scrollToPosition(topPosition)
|
b.list.scrollToPosition(topPosition)
|
||||||
} else if (bottomPosition != NO_POSITION && bottomPosition < layoutManager.findFirstCompletelyVisibleItemPosition()) {
|
} else if (bottomPosition != NO_POSITION && bottomPosition < layoutManager.findFirstVisibleItemPosition()) {
|
||||||
b.list.scrollToPosition(bottomPosition)
|
b.list.scrollToPosition(bottomPosition)
|
||||||
}
|
}
|
||||||
topPosition = NO_POSITION
|
topPosition = NO_POSITION
|
||||||
@ -121,7 +121,7 @@ class MessagesListFragment : LazyFragment(), CoroutineScope {
|
|||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
if (!isAdded) return
|
if (!isAdded) return
|
||||||
onPageDestroy?.invoke(position, Bundle(
|
onPageDestroy?.invoke(position, Bundle(
|
||||||
"topPosition" to (b.list.layoutManager as? LinearLayoutManager)?.findFirstCompletelyVisibleItemPosition(),
|
"topPosition" to (b.list.layoutManager as? LinearLayoutManager)?.findFirstVisibleItemPosition(),
|
||||||
"bottomPosition" to (b.list.layoutManager as? LinearLayoutManager)?.findLastCompletelyVisibleItemPosition()
|
"bottomPosition" to (b.list.layoutManager as? LinearLayoutManager)?.findLastCompletelyVisibleItemPosition()
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -179,71 +179,12 @@
|
|||||||
android:text="Załączniki:"
|
android:text="Załączniki:"
|
||||||
android:textAppearance="@style/NavView.TextView.Subtitle" />
|
android:textAppearance="@style/NavView.TextView.Subtitle" />
|
||||||
|
|
||||||
<LinearLayout
|
<pl.szczodrzynski.edziennik.ui.modules.views.AttachmentsView
|
||||||
android:id="@+id/attachments"
|
android:id="@+id/attachmentsFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:layout_marginHorizontal="8dp"
|
||||||
android:paddingBottom="8dp">
|
android:layout_marginBottom="8dp"/>
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:paddingRight="16dp"
|
|
||||||
tools:visibility="visible">
|
|
||||||
|
|
||||||
<com.google.android.material.chip.Chip
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ellipsize="middle"
|
|
||||||
android:text="Testowy plik.pdf"
|
|
||||||
android:visibility="visible"
|
|
||||||
app:chipBackgroundColor="@color/mtrl_chip_background_color"
|
|
||||||
app:chipIcon="@drawable/googleg_standard_color_18"
|
|
||||||
app:chipMinHeight="36dp"
|
|
||||||
app:chipSurfaceColor="@color/mtrl_chip_surface_color"
|
|
||||||
app:closeIcon="@drawable/ic_error_outline"
|
|
||||||
app:closeIconVisible="true" />
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
style="?android:attr/progressBarStyle"
|
|
||||||
android:layout_width="18dp"
|
|
||||||
android:layout_height="18dp"
|
|
||||||
android:layout_gravity="center_vertical|end"
|
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginRight="8dp" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:paddingLeft="16dp"
|
|
||||||
android:paddingRight="16dp"
|
|
||||||
tools:visibility="visible">
|
|
||||||
|
|
||||||
<com.google.android.material.chip.Chip
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ellipsize="middle"
|
|
||||||
android:text="Wyniki sprawdzianu z matematyki.pdf"
|
|
||||||
android:visibility="visible"
|
|
||||||
app:chipIcon="@drawable/googleg_standard_color_18" />
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
style="?android:attr/progressBarStyle"
|
|
||||||
android:layout_width="18dp"
|
|
||||||
android:layout_height="18dp"
|
|
||||||
android:layout_gravity="center_vertical|end"
|
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginRight="8dp" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user