diff --git a/app/build.gradle b/app/build.gradle index b4711913..4cf60147 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,16 +1,17 @@ plugins { id 'com.android.application' id 'kotlin-android' + id 'kotlin-parcelize' } android { - compileSdkVersion 30 - buildToolsVersion "30.0.3" + compileSdk 33 + buildToolsVersion "33.0.2" defaultConfig { - applicationId "otus.homework.customview" - minSdkVersion 23 - targetSdkVersion 30 + applicationId "ru.zatsoft" + minSdk 24 + targetSdk 33 versionCode 1 versionName "1.0" @@ -24,22 +25,36 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' + } + buildFeatures { + viewBinding true } } dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.3.2' - implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'com.google.android.material:material:1.3.0' - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' - testImplementation 'junit:junit:4.+' - androidTestImplementation 'androidx.test.ext:junit:1.1.2' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + constraints { + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20") { + because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib") + } + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20") { + because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib") + } + } + implementation 'androidx.core:core-ktx:1.10.1' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.9.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + implementation 'com.google.code.gson:gson:2.10.1' + implementation 'androidx.activity:activity-ktx:1.7.2' + implementation 'androidx.navigation:navigation-fragment:2.6.0' + + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index efd1e519..8355889a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,19 +1,21 @@ - + android:theme="@style/Theme.CustomView" + tools:targetApi="31"> + - diff --git a/app/src/main/java/otus/homework/customview/ListData.kt b/app/src/main/java/otus/homework/customview/ListData.kt new file mode 100644 index 00000000..273aa8d7 --- /dev/null +++ b/app/src/main/java/otus/homework/customview/ListData.kt @@ -0,0 +1,10 @@ +package otus.homework.customview + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + + +@Parcelize +data class ListData( + var data: Map +) : Parcelable diff --git a/app/src/main/java/otus/homework/customview/MainActivity.kt b/app/src/main/java/otus/homework/customview/MainActivity.kt index 78cb9448..fd63e988 100644 --- a/app/src/main/java/otus/homework/customview/MainActivity.kt +++ b/app/src/main/java/otus/homework/customview/MainActivity.kt @@ -1,11 +1,44 @@ package otus.homework.customview -import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import com.google.android.material.tabs.TabLayoutMediator +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import otus.homework.customview.databinding.ActivityMainBinding +import java.nio.charset.Charset class MainActivity : AppCompatActivity() { + private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) + configureTabLayout() + val adapter = TabPagerAdapter(this, binding.tabLayout.tabCount) + binding.viewPager.adapter = adapter + TabLayoutMediator(binding.tabLayout, binding.viewPager) + { tab, position -> + tab.text = MYTITLE.get(position) + }.attach() + } + + private fun configureTabLayout() { + repeat(2) { + binding.tabLayout.addTab(binding.tabLayout.newTab()) + } + } + + companion object { + private val MYTITLE = listOf("PIE CHART", "LINE CHART") + val myData = loadData() + + fun loadData(): List { + val gson = Gson() + val type = object : TypeToken>() {}.type + MyApp.myResource.reset() + val myJson = MyApp.myResource.bufferedReader(Charset.defaultCharset()) + return gson.fromJson(myJson, type) + } } } \ No newline at end of file diff --git a/app/src/main/java/otus/homework/customview/MyApp.kt b/app/src/main/java/otus/homework/customview/MyApp.kt new file mode 100644 index 00000000..926860c9 --- /dev/null +++ b/app/src/main/java/otus/homework/customview/MyApp.kt @@ -0,0 +1,16 @@ +package otus.homework.customview + +import android.app.Application +import java.io.InputStream + +class MyApp : Application() { + companion object { + lateinit var myResource: InputStream + } + + override fun onCreate() { + super.onCreate() + myResource = this.resources.openRawResource(R.raw.payload) + } + +} \ No newline at end of file diff --git a/app/src/main/java/otus/homework/customview/PayLoad.kt b/app/src/main/java/otus/homework/customview/PayLoad.kt new file mode 100644 index 00000000..75d6b68c --- /dev/null +++ b/app/src/main/java/otus/homework/customview/PayLoad.kt @@ -0,0 +1,13 @@ +package otus.homework.customview + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class PayLoad( + val id: Long, + val name: String, + val amount: Int, + val category: String, + val time: Long +): Parcelable diff --git a/app/src/main/java/otus/homework/customview/Tab1Fragment.kt b/app/src/main/java/otus/homework/customview/Tab1Fragment.kt new file mode 100644 index 00000000..a056480b --- /dev/null +++ b/app/src/main/java/otus/homework/customview/Tab1Fragment.kt @@ -0,0 +1,33 @@ +package otus.homework.customview + +import android.net.Uri +import android.os.Bundle +import android.view.View +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import otus.homework.customview.databinding.FragmentTab1Binding +import otus.homework.customview.piechart.ChartModel + +class Tab1Fragment : Fragment(R.layout.fragment_tab1) { + val chartModel: ChartModel by viewModels() + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val binding = FragmentTab1Binding.bind(view) + binding.chartView.chartModel = chartModel + + val touchDown = binding.chartView._clickSector + touchDown.observe(viewLifecycleOwner, { + chartModel.setChecked(it) + chartModel.setScale(it) + binding.chartView.invalidate() + }) + } + + interface OnFragmentInteractionListener { + fun onFragmentInteraction(uri: Uri) + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/homework/customview/Tab2Fragment.kt b/app/src/main/java/otus/homework/customview/Tab2Fragment.kt new file mode 100644 index 00000000..72ef958d --- /dev/null +++ b/app/src/main/java/otus/homework/customview/Tab2Fragment.kt @@ -0,0 +1,26 @@ +package otus.homework.customview + +import android.net.Uri +import android.os.Bundle +import android.view.View +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import otus.homework.customview.databinding.FragmentTab2Binding + +class Tab2Fragment : Fragment(R.layout.fragment_tab2) { + val chartModel: LineChartModel by viewModels() + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val binding = FragmentTab2Binding.bind(view) + binding.chartView.lineChartModel = chartModel + + } + + interface OnFragmentInteractionListener { + fun onFragmentInteraction(uri: Uri) + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/homework/customview/TabPagerAdapter.kt b/app/src/main/java/otus/homework/customview/TabPagerAdapter.kt new file mode 100644 index 00000000..10e009af --- /dev/null +++ b/app/src/main/java/otus/homework/customview/TabPagerAdapter.kt @@ -0,0 +1,22 @@ +package otus.homework.customview + +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter + +class TabPagerAdapter( + fa: FragmentActivity, + private var tabCount: Int +) : FragmentStateAdapter(fa) { + override fun createFragment(position: Int): Fragment { + return when (position) { + 0 -> Tab1Fragment() + 1 -> Tab2Fragment() + else -> Tab1Fragment() + } + } + + override fun getItemCount(): Int { + return tabCount + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/homework/customview/linechart/LineChartModel.kt b/app/src/main/java/otus/homework/customview/linechart/LineChartModel.kt new file mode 100644 index 00000000..453275e8 --- /dev/null +++ b/app/src/main/java/otus/homework/customview/linechart/LineChartModel.kt @@ -0,0 +1,24 @@ +package otus.homework.customview + +import androidx.lifecycle.ViewModel + +class LineChartModel : ViewModel() { + + var grafData: Map + var maxAmount = 0 + var maxTime = 0L + var minTime = 0L + + init { + + grafData = MainActivity.myData + .groupBy { it.time } + .mapValues { + it.value.map { it.amount } + .fold(0) { summ, time -> summ + time } + } + maxAmount = grafData.maxOf { it.value } + maxTime = grafData.maxOf { it.key } + minTime = grafData.minOf { it.key } + } +} diff --git a/app/src/main/java/otus/homework/customview/linechart/LineChartView.kt b/app/src/main/java/otus/homework/customview/linechart/LineChartView.kt new file mode 100644 index 00000000..27c2f1fc --- /dev/null +++ b/app/src/main/java/otus/homework/customview/linechart/LineChartView.kt @@ -0,0 +1,185 @@ +package otus.homework.customview.linechart + +import android.content.Context +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.graphics.PointF +import android.os.Bundle +import android.os.Parcelable +import android.util.AttributeSet +import android.view.GestureDetector +import android.view.MotionEvent +import android.view.View +import android.widget.Toast +import otus.homework.customview.LineChartModel +import java.text.SimpleDateFormat +import java.util.* + +class LineChartView : View { + constructor(context: Context?) : super(context) + constructor(context: Context?, attributeSet: AttributeSet?) : super(context, attributeSet) + + companion object { + private const val AXIS_X_DIVIDER = 10 + private const val AXIS_Y_DIVIDER = 10 + } + + var lineChartModel = LineChartModel() + + private val gestureDetector = GestureDetector(context, TouchView()) + private val pChart = Paint() + private val pPoint = Paint() + + + private var startX = 0f + private var startY = 0f + private var stopX = 0f + private var stopY = 0f + private var scaleTime = 1f + private var scaleAmount = 1f + private var timeWidth = 0L + private var lineDX = 0f + private var lineDY = 0f + private var graf: MutableList = mutableListOf() + private var startPoint = PointF(startX, stopY) + private var currentPoint = PointF(0f, 0f) + + init { + isSaveEnabled = true + pChart.isAntiAlias = true + pChart.style = Paint.Style.FILL + pChart.setColor(Color.WHITE) + + pPoint.style = Paint.Style.FILL_AND_STROKE + pPoint.setStrokeWidth(20f) + pPoint.color = Color.BLUE + timeWidth = lineChartModel.maxTime - lineChartModel.minTime + + } + + override fun onSaveInstanceState(): Parcelable { + val bundle = Bundle() + bundle.putParcelable("superState", super.onSaveInstanceState()) + return bundle + } + + override fun onRestoreInstanceState(state: Parcelable?) { + var viewState = state + if (viewState is Bundle) { + viewState = viewState.getParcelable("superState") + } + super.onRestoreInstanceState(viewState) + } + + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec) + val finalWidth = (getMeasuredWidth() * 0.9).toInt() + val finalHeight = (getMeasuredHeight() * 0.9).toInt() + System.out.println("finalWidth $finalWidth finalHeight $finalHeight") + setMeasuredDimension(finalWidth, finalHeight) + } + + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + startX = width * 0.15f + startY = 0f + stopX = width.toFloat() + stopY = height * 0.9f + lineDX = (stopX - startX) / AXIS_X_DIVIDER + lineDY = (stopY - startY) / AXIS_Y_DIVIDER + scaleTime = if (timeWidth > 0L) + (stopX - startX) / timeWidth + else + (stopX - startX) / 2.0f + + try { + scaleAmount = (stopY - startY) / lineChartModel.maxAmount + } catch (e: NullPointerException) { + Toast.makeText(context, "Нет данных ", Toast.LENGTH_LONG).show() + scaleAmount = 0f + } + + lineChartModel.grafData.forEach { t, u -> + System.out.println("t ${convertLongToTime(t)} u $u") + graf.add(PointF((t - lineChartModel.minTime) * scaleTime, u * scaleAmount)) + } + +// Шаблон + canvas.drawARGB(230, 240, 215, 205) + canvas.drawRect(startX, startY, stopX, stopY, pChart) +// Область графика + pChart.style = Paint.Style.STROKE + pChart.strokeWidth = 5f + pChart.setColor(Color.BLACK) + pChart.textSize = 30f + + canvas.drawRect(startX, startY, stopX, stopY, pChart) +// Сетка осей + for (i: Int in 1..AXIS_X_DIVIDER) { + canvas.drawLine((startX + lineDX * i), startY, (startX + lineDX * i), stopY, pChart) + } + for (i: Int in 1..AXIS_Y_DIVIDER) { + canvas.drawLine(startX, (startY + lineDY * i), stopX, (startY + lineDY * i), pChart) + } +// Пределы значений по Y + canvas.drawText( + "0", + startX - pChart.textSize, + stopY, + pChart + ) + canvas.drawText( + lineChartModel.maxAmount.toString(), + startX - (lineChartModel.maxAmount.toString().length - 1) * pChart.textSize, + startY + 30f, pChart + ) + +// Пределы значений по X + val startTime = convertLongToTime(lineChartModel.minTime) + val stopTime = convertLongToTime(lineChartModel.maxTime) + canvas.drawText(startTime, + startX, + stopY + pChart.textSize, + pChart + ) + canvas.drawText( + stopTime, + stopX - (stopTime.length- 7) * pChart.textSize, + stopY + pChart.textSize, + pChart + ) + System.out.println(" textSize ${lineChartModel.maxAmount.toString().length}") +// Построение графика + pChart.setColor(Color.RED) + graf.forEachIndexed() { index, it -> + System.out.println(" $it") + currentPoint = PointF(startX + it.x, stopY - it.y) + if (index > 0) { + canvas.drawLine( + startPoint.x, startPoint.y, + currentPoint.x, currentPoint.y, + pChart + ) + } + canvas.drawPoint(currentPoint.x, currentPoint.y, pPoint) + startPoint = PointF(currentPoint.x, currentPoint.y) + } + + + } + + override fun onTouchEvent(event: MotionEvent): Boolean { + gestureDetector.onTouchEvent(event) + + return super.onTouchEvent(event) + } + + fun convertLongToTime(time: Long): String { + val date = Date(time) + val format = SimpleDateFormat("MM.dd HH:mm:ss") + return format.format(date) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/otus/homework/customview/linechart/TouchView.kt b/app/src/main/java/otus/homework/customview/linechart/TouchView.kt new file mode 100644 index 00000000..d8fed3e4 --- /dev/null +++ b/app/src/main/java/otus/homework/customview/linechart/TouchView.kt @@ -0,0 +1,10 @@ +package otus.homework.customview.linechart + +import android.view.GestureDetector +import android.view.MotionEvent + +class TouchView: GestureDetector.SimpleOnGestureListener() { + override fun onDown(e: MotionEvent): Boolean { + return super.onDown(e) + } +} diff --git a/app/src/main/java/otus/homework/customview/piechart/ChartModel.kt b/app/src/main/java/otus/homework/customview/piechart/ChartModel.kt new file mode 100644 index 00000000..a36ed2a9 --- /dev/null +++ b/app/src/main/java/otus/homework/customview/piechart/ChartModel.kt @@ -0,0 +1,61 @@ +package otus.homework.customview.piechart + +import androidx.lifecycle.ViewModel +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import otus.homework.customview.MainActivity +import otus.homework.customview.MyApp.Companion.myResource +import otus.homework.customview.PayLoad +import java.nio.charset.Charset +import java.util.* +import java.util.Collections.emptyList + +class ChartModel : ViewModel() { + + var pieData: Map = HashMap() + var beginArc = ArrayList() + var lengthArc = ArrayList() + var scaleArc: List + var checkedIndex: Int = -1 + private val sumData: Int + private var startAngle = 0f + private var sweepAngle = 0f + + init { + pieData = pieGrafData() + sumData = pieData.map{it.value}.sum() + pieData.forEach { _, i -> + beginArc.add(startAngle) + sweepAngle = (i * 360f) / sumData + lengthArc.add(sweepAngle) + System.out.println("startAngle $startAngle") + startAngle += sweepAngle + } + scaleArc = emptyList() + scaleArc = pieData.map {_ -> 1.0f} + } + + fun pieGrafData() = MainActivity.myData.groupingBy {it.category } + .fold(0) { summ, category -> summ + category.amount } + + fun loadData(): List { + val gson = Gson() + val type = object : TypeToken>() {}.type + myResource.reset() + val myJson = myResource.bufferedReader(Charset.defaultCharset()) + return gson.fromJson(myJson, type) + } + + fun setScale(sector: Int) { + scaleArc = scaleArc.mapIndexed { index, _ -> + if (index == sector) + 1.05f + else + 1.0f + } + } + + fun setChecked(index: Int) { + checkedIndex = index + } +} diff --git a/app/src/main/java/otus/homework/customview/piechart/PieChartView.kt b/app/src/main/java/otus/homework/customview/piechart/PieChartView.kt new file mode 100644 index 00000000..9519243a --- /dev/null +++ b/app/src/main/java/otus/homework/customview/piechart/PieChartView.kt @@ -0,0 +1,157 @@ +package otus.homework.customview.piechart + +import android.content.Context +import android.graphics.* +import android.os.Bundle +import android.os.Parcelable +import android.util.AttributeSet +import android.view.GestureDetector +import android.view.MotionEvent +import android.view.View +import androidx.lifecycle.MutableLiveData +import otus.homework.customview.piechart.ChartModel +import otus.homework.customview.piechart.TouchView +import kotlin.math.pow + +class PieChartView : View { + constructor(context: Context?) : super(context) + constructor(context: Context?, attributeSet: AttributeSet?) : super(context, attributeSet) + + var chartModel = ChartModel() + + lateinit var cycleCenter: PointF + var _clickSector = MutableLiveData(-1) + + private val gestureDetector = GestureDetector(context, TouchView()) + private val pChart = Paint() + private val pText = Paint() + private val rec = RectF() + private val color = arrayOf( + Color.RED, + Color.BLUE, + -0x886699, + -0x11BB88, + Color.CYAN, + Color.GRAY, + Color.YELLOW, + Color.MAGENTA, + Color.GREEN + ) + private var startLeft = 0f + private var startTop = 0f + private var midHeight = 0f + private var midWidth = 0f + + init { + rec.left = 0f + rec.top = 0f + isSaveEnabled = true + pChart.isAntiAlias = true + pChart.style = Paint.Style.STROKE + pChart.strokeWidth = 40f + pText.textSize = 20f + pText.style = Paint.Style.FILL_AND_STROKE + pText.setStrokeWidth(2f) + + } + + override fun onSaveInstanceState(): Parcelable { + val bundle = Bundle() + bundle.putParcelable("superState", super.onSaveInstanceState()) + return bundle + } + + override fun onRestoreInstanceState(state: Parcelable?) { + var viewState = state + if (viewState is Bundle) { + viewState = viewState.getParcelable("superState") + } + super.onRestoreInstanceState(viewState) + } + + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec) + val size = Math.min(getMeasuredWidth(), getMeasuredHeight()) + val finalWidth = size + val finalHeight = size + System.out.println("finalWidth $finalWidth finalHeight $finalHeight") + setMeasuredDimension(finalWidth, finalHeight) + } + + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + midHeight = Math.min(height, width) / 2f + midWidth = midHeight + startLeft = width * 0.1f + startTop = height * 0.1f + // Шаблон + canvas.drawARGB(230, 400, 150, 50) +// Сдвиг для правильного отображения в landscape + canvas.translate(0f, height / 4f) +// Рисование pieChart + cycleCenter = + PointF((midWidth + startLeft) / 2, (midHeight + startLeft) / 2 + height / 4f) + var j = 0 + + chartModel.pieData.forEach { s, _ -> + pChart.color = color[j % color.size] + canvas.drawArc( + startLeft - midWidth * (chartModel.scaleArc[j] - 1f), + startTop - midHeight * (chartModel.scaleArc[j] - 1f), + midWidth * chartModel.scaleArc[j], + midHeight * chartModel.scaleArc[j], + chartModel.beginArc.get(j), chartModel.lengthArc.get(j), + false, + pChart + ) +// В таблицу наименований + canvas.translate(midWidth * 1.2f, j * 50f) + if (j == chartModel.checkedIndex) { + textDraw(canvas, pText, pChart, s + " !!") + } else { + textDraw(canvas, pText, pChart, s) + } + canvas.translate(-midWidth * 1.2f, -j * 50f) + j++ + } + } + + private fun textDraw(canvas: Canvas, p: Paint, pBack: Paint, text: String) { + val rect = Rect(20, 20, 170, 23) + canvas.drawRect(rect, pBack) + canvas.drawText(text, 10f, 25f, p) + } + + override fun onTouchEvent(event: MotionEvent): Boolean { + gestureDetector.onTouchEvent(event) + val angle: Double + val lenghtX = event.x - cycleCenter.x + val lenghtY = event.y - cycleCenter.y + val touchVector = Math.sqrt( + (lenghtX.pow(2) + lenghtY.pow(2)).toDouble() + ) + if (touchVector < midHeight / 2) { + angle = (Math.atan((lenghtY / lenghtX).toDouble()) / Math.PI * 180).let { + if (lenghtX < 0f) { + it.plus(180.0) + } else { + if (lenghtY < 0f) { + it.plus(360.0) + } else { + it + } + } + } + run breaking@{ + chartModel.beginArc.forEachIndexed { index, beginAngle -> + if (beginAngle > angle) { + _clickSector.value = index - 1 + return@breaking + } + } + _clickSector.value = chartModel.beginArc.size - 1 + } + } + return super.onTouchEvent(event) + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/homework/customview/piechart/TouchView.kt b/app/src/main/java/otus/homework/customview/piechart/TouchView.kt new file mode 100644 index 00000000..e8331215 --- /dev/null +++ b/app/src/main/java/otus/homework/customview/piechart/TouchView.kt @@ -0,0 +1,10 @@ +package otus.homework.customview.piechart + +import android.view.GestureDetector +import android.view.MotionEvent + +class TouchView : GestureDetector.SimpleOnGestureListener() { + override fun onDown(e: MotionEvent): Boolean { + return super.onDown(e) + } +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 79ae6993..37e1f577 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -5,15 +5,38 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".MainActivity"> + tools:context="otus.homework.customview.MainActivity"> - + + + + + + /> \ No newline at end of file diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml new file mode 100644 index 00000000..e416e1c1 --- /dev/null +++ b/app/src/main/res/layout/content_main.xml @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_tab1.xml b/app/src/main/res/layout/fragment_tab1.xml new file mode 100644 index 00000000..0bdf898c --- /dev/null +++ b/app/src/main/res/layout/fragment_tab1.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_tab2.xml b/app/src/main/res/layout/fragment_tab2.xml new file mode 100644 index 00000000..ad34a718 --- /dev/null +++ b/app/src/main/res/layout/fragment_tab2.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9213c339..3f4437da 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,6 @@ Custom View + Line Chart + Pie Chart + Tab 1 Fragment \ No newline at end of file diff --git a/build.gradle b/build.gradle index e47bb55b..0035d82a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,25 +1,17 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = "1.4.32" + ext.kotlin_version = '1.7.1' repositories { google() - jcenter() - } - dependencies { - classpath "com.android.tools.build:gradle:4.1.2" - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + mavenCentral() + }} - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } +plugins { + id 'com.android.application' version '7.2.2' apply false + id 'com.android.library' version '7.2.2' apply false + id 'org.jetbrains.kotlin.android' version '1.7.0' apply false } -allprojects { - repositories { - google() - jcenter() - } -} task clean(type: Delete) { delete rootProject.buildDir diff --git a/gradle.properties b/gradle.properties index 98bed167..ca36a32b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,4 +18,5 @@ android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official \ No newline at end of file +kotlin.code.style=official +org.gradle.unsafe.configuration-cache=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8734448b..1f5a55ab 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Jun 11 17:42:46 MSK 2021 +#Wed Nov 29 17:50:58 CET 2023 distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +zipStoreBase=GRADLE_USER_HOME diff --git a/settings.gradle b/settings.gradle index 8eeb99dc..014e7b30 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,16 @@ +pluginManagement { + repositories { + gradlePluginPortal() + google() + mavenCentral() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} include ':app' rootProject.name = "Custom View" \ No newline at end of file