-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSampleCode.kt
181 lines (143 loc) · 6.37 KB
/
SampleCode.kt
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
/* This is a fragment from one of my apps, and some of its dependencies.
PlaceOrderFragment shows a pdf on the UI, and with a button click it can open an
email client app with an intent, and have the pdf automatically attached and some
information like the client's email address prefilled */
class PlaceOrderFragment: ViewPdfFragment<FragmentPlaceOrderBinding>(R.layout.fragment_place_order) {
override val viewModel by viewModels<PlaceOrderViewModel>()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
initButtons()
return binding.root
}
private fun initButtons() {
with(binding) { // (in a parent class: binding = DataBindingUtil.inflate(inflater, layoutResourceId, container, false))
okButton.setOnClickListener {
val clientEmail = clientRepo.get(currentOrder.clientId).email
emailOrder(viewModel.contentUri, clientEmail)
}
cancelButton.setOnClickListener { activity!!.onBackPressed() }
}
}
override fun onPdfGenerated() {
binding.pdf.fromFile(viewModel.orderPdf) // binding.pdf: third party pdf viewer
.onLoad { binding.okButton.isEnabled = true }
.spacing(pageSpacing)
.load()
}
private fun emailOrder(orderPdfUri: Uri, clientEmail: String) {
sendEmail(get<EmailManager>().createEmailIntent(orderPdfUri, clientEmail)) // get<>(): gets object via service locator.
// gets my implementation of my EmailManager interface
}
private fun sendEmail(emailIntent: Intent) {
startActivity(
Intent.createChooser(
emailIntent,
getString(R.string.send_email)
)
)
}
} // (by viewModels<>(): fragments ktx extension function. helps to avoid having to write factories for VMs)
// these are some of the stuff PlaceOrderFragment depends on:
// removes the duplication of common pdf viewer fragment code, (I have an other fragment that shows a pdf too)
abstract class ViewPdfFragment<ViewDataBindingType: ViewDataBinding>
(layoutResourceId: Int)
: DataBindingFragment<ViewDataBindingType>(layoutResourceId) {
abstract val viewModel: PdfViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
loadPdf()
return binding.root
}
private fun loadPdf() {
ioWork(
viewLifecycleOwner,
viewModel::generatePdf,
::onPdfGenerated
)
}
abstract fun onPdfGenerated()
companion object {
const val pageSpacing = 8
}
}
// coroutine helper to do some "work" on an IO-optimized thread, then if need be, perform some UI work (on the main thread)
fun ioWork(lifecycleOwner: LifecycleOwner?, work: () -> Unit, useUiOnComplete: () -> Unit = {}) {
(lifecycleOwner?.lifecycleScope ?: GlobalScope).launch(Dispatchers.IO) {
work()
withContext(Dispatchers.Main) { useUiOnComplete() }
}
}
// common parent fragment to remove duplications concerning creating the data binding for fragments
open class DataBindingFragment<ViewDataBindingType: ViewDataBinding>
(private val layoutResourceId: Int)
: Fragment(){
protected lateinit var binding: ViewDataBindingType
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreateView(inflater, container, savedInstanceState)
binding = DataBindingUtil.inflate(inflater, layoutResourceId, container, false)
binding.lifecycleOwner = viewLifecycleOwner
return binding.root
}
}
abstract class PdfViewModel : ViewModel(), KoinComponent {
abstract fun generatePdf()
}
class PlaceOrderViewModel: PdfViewModel() {
lateinit var orderPdf: File
lateinit var contentUri: Uri
override fun generatePdf() {
orderPdf = ManageOrdersInteractor.generateOrderPdf() // fun generateOrderPdf() = get<PdfMaker>().makeOrderPdf(currentOrder)
contentUri = MyFileProvider.getOrderPdfUri(orderPdf)
}
}
// fragment_place_order.xml:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<com.github.barteksc.pdfviewer.PDFView
android:id="@+id/pdf"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/background"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/cancel_button"
>
</com.github.barteksc.pdfviewer.PDFView>
<hu.sajti.pevdicalculator.view.SquareImageButton
android:id="@+id/cancel_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="@drawable/red_cancel"
android:scaleType="fitXY"
android:layout_margin="8dp"
app:layout_constraintWidth_percent="@dimen/button_width_ratio"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<hu.sajti.pevdicalculator.view.SquareImageButton
android:id="@+id/ok_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="@drawable/arrow_blue_right"
android:scaleType="fitXY"
android:layout_margin="8dp"
isEnabled="false"
app:layout_constraintWidth_percent="@dimen/button_width_ratio"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>