123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- package ml.adamsprogs.bimba.fragments
- import android.content.Context
- import android.os.Build
- import android.os.Bundle
- import androidx.fragment.app.Fragment
- import android.view.LayoutInflater
- import android.view.View
- import android.view.ViewGroup
- import androidx.appcompat.app.AppCompatActivity
- import androidx.appcompat.widget.Toolbar
- import com.google.android.material.appbar.AppBarLayout
- import ml.adamsprogs.bimba.R
- import ml.adamsprogs.bimba.activities.MainActivity
- import com.pedromassango.ibackdrop.Backdrop
- import kotlinx.android.synthetic.main.fragment_planning.view.*
- import android.text.Spanned
- import android.text.style.ImageSpan
- import com.google.android.material.chip.ChipDrawable
- import android.widget.*
- import android.graphics.drawable.Drawable
- import android.graphics.Canvas
- import android.graphics.Paint
- import android.text.Editable
- import android.text.SpannableStringBuilder
- import android.util.TypedValue
- import ml.adamsprogs.bimba.views.StopAutoCompleteTextView
- class PlanningFragment : Fragment(), MainActivity.OnActivityActionListener {
- private lateinit var root: View
- private lateinit var toolbar: Toolbar
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?): View? {
- root = inflater.inflate(R.layout.fragment_planning, container, false)
- root.post {
- val height = root.measuredHeight
- with(root.findViewById<Backdrop>(R.id.backdrop_view)) {
- val px = TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP,
- 48f, resources.displayMetrics).toInt()
- backdropSize = height - px
- buildWithToolbar(toolbar)
- root.arrow_icon.visibility = View.VISIBLE
- openBackdrop()
- setOnSwitchListener(object : Backdrop.OnSwitchListener {
- override fun onSwitch(hidden: Boolean) {
- root.arrow_icon.visibility = if (hidden) View.VISIBLE else View.GONE
- }
- })
- root.arrow_icon.setOnClickListener {
- closeBackdrop()
- }
- }
- }
- val activity = context as AppCompatActivity
- val appBarLayout = activity.findViewById<AppBarLayout>(R.id.appbar)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- appBarLayout.outlineProvider = null
- }
- toolbar = activity.findViewById(R.id.toolbar)
- StopsAutoCompleteEditText(root.from_input as StopAutoCompleteTextView, context as Context)
- StopsAutoCompleteEditText(root.to_input as StopAutoCompleteTextView, context as Context)
- root.search_button.setOnClickListener {
- // todo
- }
- return root
- }
- override fun onDetach() {
- super.onDetach()
- toolbar.navigationIcon = null
- }
- /*private fun getStops(view: EditText): HashSet<String> {
- val result: HashSet<String> = HashSet(1)
- for (s in view.text.toString().split(";")) {
- result.add(s)
- }
- return result
- }
- private fun search(view: View) {
- val x = Calendar.getInstance()
- val t = time.text.toString().split(":")
- x.set(Calendar.HOUR_OF_DAY, t[0].toInt())
- x.set(Calendar.MINUTE, t[1].toInt())
- route.text = RouteFinder.findRoute(getStops(start), getStops(end), x, context!!)
- for (i in 1..6) {
- x.add(Calendar.MINUTE, 6)
- val s = RouteFinder.findRoute(getStops(start), getStops(end), x, context!!)
- if (s != route.text.toString()) {
- route.text = "${route.text}\n$s"
- break
- }
- }
- }*/
- override fun onBackPressed(): Boolean {
- return false
- }
- class StopsAutoCompleteEditText(private val inputView: StopAutoCompleteTextView, val context: Context) {
- private val PEOPLE = arrayOf("John Smith", "Kate Eckhart", "Emily Sun", "Frodo Baggins")
- private val stops = ArrayList<String>()
- init {
- val adapter = StopsAdapter(context,
- android.R.layout.simple_dropdown_item_1line, PEOPLE)
- inputView.setAdapter(adapter)
- inputView.setOnKeyPressListener(object : StopAutoCompleteTextView.OnBackspacePressedListener {
- override fun onBackspacePressed(s: Editable, start: Int, end: Int) {
- val tokens = s.getSpans(0, s.length, VerticalImageSpan::class.java)
- val result = ArrayList<StopsAutoCompleteEditText.VerticalImageSpan>()
- var length = 0
- tokens.forEach {
- val textLength = (it.drawable as ChipDrawable).text.length
- if (textLength + length != start)
- result.add(it)
- length += textLength
- }
- stops.clear()
- stops.addAll(result.map {
- (it.drawable as ChipDrawable).text.toString()
- })
- }
- })
- inputView.setOnItemClickListener { parent, _, position, _ ->
- val selected = parent.getItemAtPosition(position) as String
- stops.add(selected)
- addChipToGroup()
- inputView.setSelection(inputView.text.length)
- }
- }
- private fun addChipToGroup() {
- val ss = SpannableStringBuilder()
- for (stop in stops)
- ss.append(stop)
- var l = 0
- for (stop in stops) {
- val chip = ChipDrawable.createFromResource(context, R.xml.chip)
- chip.setText(stop)
- chip.setBounds(0, 0, chip.intrinsicWidth, chip.intrinsicHeight)
- val span = VerticalImageSpan(chip) // todo margins
- ss.setSpan(span, l, l + stop.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
- l += stop.length
- }
- inputView.text = ss
- }
- inner class StopsAdapter(context: Context, val layout: Int, items: Array<String>) : BaseAdapter(), Filterable {
- private val originalData = ArrayList<String>()
- private val filteredData = ArrayList<String>()
- private val inflater = LayoutInflater.from(context)
- init {
- filteredData.addAll(items)
- originalData.addAll(items)
- }
- override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
- val view: View = convertView ?: inflater.inflate(layout, parent, false)
- val text = view as TextView
- val item = getItem(position)
- text.text = item
- return view
- }
- override fun getItemId(position: Int): Long {
- return position.toLong()
- }
- override fun getCount(): Int {
- return filteredData.size
- }
- override fun getItem(position: Int): String {
- return filteredData[position]
- }
- override fun getFilter(): Filter {
- return object : Filter() {
- override fun performFiltering(constraint: CharSequence?): FilterResults {
- val filterString = constraint.toString().replace(stops.joinToString(""), "").toLowerCase()
- val filtered = originalData.filter {
- it.toLowerCase().contains(filterString)
- }
- return FilterResults().apply {
- values = filtered
- this.count = filtered.size
- }
- }
- override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
- filteredData.clear()
- @Suppress("UNCHECKED_CAST")
- filteredData.addAll(results?.values as ArrayList<String>)
- notifyDataSetChanged()
- }
- }
- }
- }
- inner class VerticalImageSpan(drawable: Drawable) : ImageSpan(drawable) {
- override fun getSize(paint: Paint, text: CharSequence, start: Int, end: Int,
- fontMetricsInt: Paint.FontMetricsInt?): Int {
- val drawable = drawable
- val rect = drawable.bounds
- if (fontMetricsInt != null) {
- val fmPaint = paint.fontMetricsInt
- val fontHeight = fmPaint.descent - fmPaint.ascent
- val drHeight = rect.bottom - rect.top
- val centerY = fmPaint.ascent + fontHeight / 2
- fontMetricsInt.ascent = centerY - drHeight / 2
- fontMetricsInt.top = fontMetricsInt.ascent
- fontMetricsInt.bottom = centerY + drHeight / 2
- fontMetricsInt.descent = fontMetricsInt.bottom
- }
- return rect.right
- }
- override fun draw(canvas: Canvas, text: CharSequence, start: Int, end: Int,
- x: Float, top: Int, y: Int, bottom: Int, paint: Paint) {
- val drawable = drawable
- canvas.save()
- val fmPaint = paint.fontMetricsInt
- val fontHeight = fmPaint.descent - fmPaint.ascent
- val centerY = y + fmPaint.descent - fontHeight / 2
- val transY = centerY - (drawable.bounds.bottom - drawable.bounds.top) / 2
- canvas.translate(x, transY.toFloat())
- drawable.draw(canvas)
- canvas.restore()
- }
- }
- }
- }
|