init
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/caches
|
||||||
|
/.idea/libraries
|
||||||
|
/.idea/modules.xml
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/navEditor.xml
|
||||||
|
/.idea/assetWizardSettings.xml
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
|
.cxx
|
||||||
|
local.properties
|
||||||
1
app/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
52
app/build.gradle.kts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
plugins {
|
||||||
|
alias(libs.plugins.androidApplication)
|
||||||
|
alias(libs.plugins.jetbrainsKotlinAndroid)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "com.example.accountbook"
|
||||||
|
compileSdk = 34
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId = "com.example.accountbook"
|
||||||
|
minSdk = 28
|
||||||
|
targetSdk = 34
|
||||||
|
versionCode = 1
|
||||||
|
versionName = "1.0"
|
||||||
|
|
||||||
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
isMinifyEnabled = false
|
||||||
|
proguardFiles(
|
||||||
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
|
"proguard-rules.pro"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
buildFeatures {
|
||||||
|
viewBinding = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(libs.androidx.core.ktx)
|
||||||
|
implementation(libs.androidx.appcompat)
|
||||||
|
implementation(libs.material)
|
||||||
|
implementation(libs.androidx.constraintlayout)
|
||||||
|
implementation(libs.androidx.navigation.fragment.ktx)
|
||||||
|
implementation(libs.androidx.navigation.ui.ktx)
|
||||||
|
testImplementation(libs.junit)
|
||||||
|
androidTestImplementation(libs.androidx.junit)
|
||||||
|
androidTestImplementation(libs.androidx.espresso.core)
|
||||||
|
}
|
||||||
21
app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.example.accountbook
|
||||||
|
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumented test, which will execute on an Android device.
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class ExampleInstrumentedTest {
|
||||||
|
@Test
|
||||||
|
fun useAppContext() {
|
||||||
|
// Context of the app under test.
|
||||||
|
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
|
assertEquals("com.example.accountbook", appContext.packageName)
|
||||||
|
}
|
||||||
|
}
|
||||||
43
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/Theme.AccountBook"
|
||||||
|
tools:targetApi="31">
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:theme="@style/Theme.AccountBook">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".activity.ActivityCalendar"
|
||||||
|
android:exported="true"
|
||||||
|
android:theme="@style/Theme.AccountBook">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".activity.ActivityWriter"
|
||||||
|
android:exported="true"
|
||||||
|
android:theme="@style/Theme.AccountBook">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
44
app/src/main/java/com/example/accountbook/FirstFragment.kt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package com.example.accountbook
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import com.example.accountbook.databinding.FragmentFirstBinding
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple [Fragment] subclass as the default destination in the navigation.
|
||||||
|
*/
|
||||||
|
class FirstFragment : Fragment() {
|
||||||
|
|
||||||
|
private var _binding: FragmentFirstBinding? = null
|
||||||
|
|
||||||
|
// This property is only valid between onCreateView and
|
||||||
|
// onDestroyView.
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
|
||||||
|
_binding = FragmentFirstBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
// binding.buttonFirst.setOnClickListener {
|
||||||
|
// findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
}
|
||||||
63
app/src/main/java/com/example/accountbook/MainActivity.kt
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package com.example.accountbook
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.navigation.findNavController
|
||||||
|
import androidx.navigation.ui.AppBarConfiguration
|
||||||
|
import androidx.navigation.ui.navigateUp
|
||||||
|
import androidx.navigation.ui.setupActionBarWithNavController
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
|
import com.example.accountbook.activity.ActivityCalendar
|
||||||
|
import com.example.accountbook.databinding.ActivityMainBinding
|
||||||
|
|
||||||
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var appBarConfiguration: AppBarConfiguration
|
||||||
|
private lateinit var binding: ActivityMainBinding
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
setSupportActionBar(binding.toolbar)
|
||||||
|
|
||||||
|
val navController = findNavController(R.id.nav_host_fragment_content_main)
|
||||||
|
appBarConfiguration = AppBarConfiguration(navController.graph)
|
||||||
|
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||||
|
|
||||||
|
binding.fab.setOnClickListener { view ->
|
||||||
|
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
|
||||||
|
.setAction("Action", null)
|
||||||
|
.setAnchorView(R.id.fab).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
startActivity(Intent(applicationContext, ActivityCalendar::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
|
// Inflate the menu; this adds items to the action bar if it is present.
|
||||||
|
menuInflater.inflate(R.menu.menu_main, menu)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
// Handle action bar item clicks here. The action bar will
|
||||||
|
// automatically handle clicks on the Home/Up button, so long
|
||||||
|
// as you specify a parent activity in AndroidManifest.xml.
|
||||||
|
return when (item.itemId) {
|
||||||
|
R.id.action_settings -> true
|
||||||
|
else -> super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSupportNavigateUp(): Boolean {
|
||||||
|
val navController = findNavController(R.id.nav_host_fragment_content_main)
|
||||||
|
return navController.navigateUp(appBarConfiguration)
|
||||||
|
|| super.onSupportNavigateUp()
|
||||||
|
}
|
||||||
|
}
|
||||||
44
app/src/main/java/com/example/accountbook/SecondFragment.kt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package com.example.accountbook
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import com.example.accountbook.databinding.FragmentSecondBinding
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple [Fragment] subclass as the second destination in the navigation.
|
||||||
|
*/
|
||||||
|
class SecondFragment : Fragment() {
|
||||||
|
|
||||||
|
private var _binding: FragmentSecondBinding? = null
|
||||||
|
|
||||||
|
// This property is only valid between onCreateView and
|
||||||
|
// onDestroyView.
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
|
||||||
|
_binding = FragmentSecondBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
binding.buttonSecond.setOnClickListener {
|
||||||
|
findNavController().navigate(R.id.action_SecondFragment_to_FirstFragment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
package com.example.accountbook.activity
|
||||||
|
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.BaseAdapter
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import com.example.accountbook.R
|
||||||
|
import com.example.accountbook.calendar.CalendarAdapter
|
||||||
|
import com.example.accountbook.calendar.CalendarBean
|
||||||
|
import com.example.accountbook.calendar.CalendarDateView
|
||||||
|
import com.example.accountbook.databinding.ActivityCalendarBinding
|
||||||
|
import com.example.accountbook.fragment.FragmentCalendar
|
||||||
|
import com.example.accountbook.fragment.FragmentTable
|
||||||
|
|
||||||
|
class ActivityCalendar: AppCompatActivity(){
|
||||||
|
private lateinit var bind: ActivityCalendarBinding
|
||||||
|
val fragmentCalendar: FragmentCalendar by lazy { FragmentCalendar() }
|
||||||
|
val fragmentTable: FragmentTable by lazy { FragmentTable() }
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
// binding view
|
||||||
|
bind = ActivityCalendarBinding.inflate(this.layoutInflater)
|
||||||
|
// setting content view
|
||||||
|
setContentView(bind.root)
|
||||||
|
bind.chkShift.setOnClickListener() { _ ->
|
||||||
|
// 화면 전환
|
||||||
|
supportFragmentManager.beginTransaction()
|
||||||
|
.replace(
|
||||||
|
R.id.fragment_box,
|
||||||
|
if (bind.chkShift.isChecked) fragmentTable else fragmentCalendar
|
||||||
|
)
|
||||||
|
.commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
supportFragmentManager.beginTransaction()
|
||||||
|
.replace(
|
||||||
|
R.id.fragment_box, fragmentCalendar
|
||||||
|
)
|
||||||
|
.commit()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package com.example.accountbook.activity
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.example.accountbook.R
|
||||||
|
import com.example.accountbook.databinding.ActivityWriterBinding
|
||||||
|
|
||||||
|
class ActivityWriter: AppCompatActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
val bind = ActivityWriterBinding.inflate(this.layoutInflater)
|
||||||
|
setContentView(bind.root)
|
||||||
|
val adapter = ArrayAdapter<String>(this, R.layout.item_spinner_writer_category, arrayListOf("기타","식비","통신비","급여"))
|
||||||
|
bind.spinnerWriteCategory.adapter = adapter
|
||||||
|
bind.btnWriteClose.setOnClickListener{
|
||||||
|
this.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package com.example.accountbook.adapter
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import com.example.accountbook.R
|
||||||
|
import com.example.accountbook.databinding.ItemTableBinding
|
||||||
|
|
||||||
|
class AdapterTable(context: Context, private val data: Array<String>):
|
||||||
|
ArrayAdapter<String>(context, R.layout.item_table, data) {
|
||||||
|
private lateinit var bind:ItemTableBinding
|
||||||
|
|
||||||
|
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||||
|
var rView: View? = convertView
|
||||||
|
if (rView == null) {
|
||||||
|
// 최초 생성
|
||||||
|
bind = ItemTableBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
|
}
|
||||||
|
bind.textDate.text = "10/25"
|
||||||
|
bind.textAmount.text = "10,000"
|
||||||
|
bind.textMemo.text = "커피"
|
||||||
|
bind.textCategory.text = "기타"
|
||||||
|
return bind.root
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package com.example.accountbook.calendar
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
|
||||||
|
|
||||||
|
interface CalendarAdapter {
|
||||||
|
fun getView(convertView: View?, parentView: ViewGroup?, bean: CalendarBean?): View
|
||||||
|
fun hasChildView() : Boolean
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
package com.example.accountbook.calendar;
|
||||||
|
|
||||||
|
public class CalendarBean {
|
||||||
|
public int year;
|
||||||
|
public int month;
|
||||||
|
public int day;
|
||||||
|
public int week;
|
||||||
|
|
||||||
|
//-1,0,1
|
||||||
|
public int monthFlag;
|
||||||
|
|
||||||
|
//显示
|
||||||
|
|
||||||
|
public CalendarBean(int year, int month, int day) {
|
||||||
|
this.year = year;
|
||||||
|
this.month = month;
|
||||||
|
this.day = day;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayWeek(){
|
||||||
|
String s="";
|
||||||
|
switch(week){
|
||||||
|
case 1:
|
||||||
|
s="星期日";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
s="星期一";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
s="星期二";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
s="星期三";
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
s="星期四";
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
s="星期五";
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
s="星期六";
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
return s ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String s=year+"/"+month+"/"+day;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,138 @@
|
|||||||
|
package com.example.accountbook.calendar
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.viewpager.widget.PagerAdapter
|
||||||
|
import androidx.viewpager.widget.ViewPager
|
||||||
|
import com.example.accountbook.R
|
||||||
|
import com.example.accountbook.calendar.CalendarFactory.getMonthOfDayList
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.LinkedList
|
||||||
|
|
||||||
|
|
||||||
|
class CalendarDateView(context: Context, attrs: AttributeSet?):
|
||||||
|
ViewPager(context, attrs), CalendarTopView {
|
||||||
|
var views = HashMap<Int, CalendarView>()
|
||||||
|
private var mCaledarLayoutChangeListener: CalendarTopViewChangeListener? = null
|
||||||
|
private var onItemClickListener: CalendarView.OnItemClickListener? = null
|
||||||
|
private val cache: LinkedList<CalendarView?> = LinkedList<CalendarView?>()
|
||||||
|
private val MAXCOUNT = 6
|
||||||
|
private var row = 6
|
||||||
|
private var mAdapter: CalendarAdapter? = null
|
||||||
|
override var itemHeight = 0
|
||||||
|
private set
|
||||||
|
|
||||||
|
|
||||||
|
fun setAdapter(adapter: CalendarAdapter?) {
|
||||||
|
mAdapter = adapter
|
||||||
|
initialize()
|
||||||
|
initData()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setOnItemClickListener(onItemClickListener: CalendarView.OnItemClickListener?) {
|
||||||
|
this.onItemClickListener = onItemClickListener
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val a = context.obtainStyledAttributes(attrs, R.styleable.CalendarDateView)
|
||||||
|
row = a.getInteger(R.styleable.CalendarDateView_cbd_calendar_row, 6)
|
||||||
|
a.recycle()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||||
|
// var calendarHeight = 0
|
||||||
|
if (adapter != null) {
|
||||||
|
(getChildAt(0) as CalendarView)?.let {
|
||||||
|
// calendarHeight = it.measuredHeight
|
||||||
|
itemHeight = it.itemHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setMeasuredDimension(
|
||||||
|
widthMeasureSpec,
|
||||||
|
MeasureSpec.makeMeasureSpec(heightMeasureSpec, MeasureSpec.EXACTLY)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initialize() {
|
||||||
|
val dateArr: IntArray = CalendarUtil.getYMD(Date())
|
||||||
|
setAdapter(object : PagerAdapter() {
|
||||||
|
override fun getCount(): Int {
|
||||||
|
// Log.i(this@CalendarDateView::class.java.simpleName, "container >>> setAdapter getCount")
|
||||||
|
return Int.MAX_VALUE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isViewFromObject(view: View, `object`: Any): Boolean {
|
||||||
|
return view === `object`
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun instantiateItem(container: ViewGroup, position: Int): Any {
|
||||||
|
|
||||||
|
Log.i(this@CalendarDateView::class.java.simpleName, "container >>> ${container} position >> ${position}")
|
||||||
|
val view: CalendarView = if (!cache.isEmpty()) {
|
||||||
|
cache.removeFirst()!!
|
||||||
|
} else {
|
||||||
|
CalendarView(container.context, row)
|
||||||
|
}
|
||||||
|
view.setOnItemClickListener(onItemClickListener)
|
||||||
|
view.setAdapter(mAdapter)
|
||||||
|
|
||||||
|
container.addView(view)
|
||||||
|
views[position] = view
|
||||||
|
view.apply {
|
||||||
|
setData(
|
||||||
|
getMonthOfDayList(
|
||||||
|
dateArr[0],
|
||||||
|
dateArr[1] + position - Int.MAX_VALUE / 2
|
||||||
|
), position == Int.MAX_VALUE / 2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
|
||||||
|
container.removeView(`object` as View)
|
||||||
|
cache.addLast(`object` as CalendarView)
|
||||||
|
views.remove(position)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
addOnPageChangeListener(object: SimpleOnPageChangeListener() {
|
||||||
|
override fun onPageSelected(position: Int) {
|
||||||
|
super.onPageSelected(position)
|
||||||
|
onItemClickListener?.let{
|
||||||
|
views[position]?.let {v ->
|
||||||
|
val obs: Array<Any> = v.select
|
||||||
|
it.onItemClick(
|
||||||
|
obs[0] as View,
|
||||||
|
obs[1] as Int,
|
||||||
|
obs[2] as CalendarBean
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mCaledarLayoutChangeListener?.onLayoutChange(this@CalendarDateView)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initData() {
|
||||||
|
setCurrentItem(Int.MAX_VALUE / 2, false)
|
||||||
|
adapter!!.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val currentSelectPositon: IntArray
|
||||||
|
get() {
|
||||||
|
var view = views[currentItem]
|
||||||
|
if (view == null) {
|
||||||
|
view = getChildAt(0) as? CalendarView
|
||||||
|
}
|
||||||
|
return view?.getSelectPosition() ?: IntArray(4)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setCalendarTopViewChangeListener(listener: CalendarTopViewChangeListener?) {
|
||||||
|
mCaledarLayoutChangeListener = listener
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
package com.example.accountbook.calendar
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import com.example.accountbook.calendar.CalendarUtil.getDayOfWeek
|
||||||
|
import java.util.Calendar
|
||||||
|
|
||||||
|
|
||||||
|
object CalendarFactory {
|
||||||
|
private val cache = HashMap<String, List<CalendarBean>>()
|
||||||
|
|
||||||
|
fun getMonthOfDayList(y: Int, m: Int): List<CalendarBean> {
|
||||||
|
Log.e("TIME CHECK" , "fun getMonthOfDayList Start")
|
||||||
|
val key = y.toString() + "" + m
|
||||||
|
if (cache.containsKey(key)) {
|
||||||
|
val list = cache[key]
|
||||||
|
if (list == null) {
|
||||||
|
cache.remove(key)
|
||||||
|
} else {
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val list: MutableList<CalendarBean> = ArrayList()
|
||||||
|
cache[key] = list
|
||||||
|
|
||||||
|
val fweek: Int = getDayOfWeek(y, m, 1)
|
||||||
|
val total: Int = CalendarUtil.getDayOfMaonth(y, m)
|
||||||
|
|
||||||
|
for (i in fweek - 1 downTo 1) {
|
||||||
|
val bean = getCalendarBean(y, m, 1 - i)
|
||||||
|
bean.monthFlag = -1
|
||||||
|
list.add(bean)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in 0 until total) {
|
||||||
|
val bean = getCalendarBean(y, m, i + 1)
|
||||||
|
list.add(bean)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in 0 until 42 - (fweek - 1) - total) {
|
||||||
|
val bean = getCalendarBean(y, m, total + i + 1)
|
||||||
|
bean.monthFlag = 1
|
||||||
|
list.add(bean)
|
||||||
|
}
|
||||||
|
Log.e("TIME CHECK" , "fun getMonthOfDayList END")
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCalendarBean(year: Int, month: Int, day: Int): CalendarBean {
|
||||||
|
|
||||||
|
val calendar: Calendar = Calendar.getInstance()
|
||||||
|
.apply { this.set(year, month - 1, day) }
|
||||||
|
val year = calendar.get(Calendar.YEAR)
|
||||||
|
val month = calendar.get(Calendar.MONTH) + 1
|
||||||
|
val day = calendar.get(Calendar.DATE)
|
||||||
|
val bean = CalendarBean(year, month, day)
|
||||||
|
bean.week = CalendarUtil.getDayOfWeek(year, month, day)
|
||||||
|
// val chinaDate: Array<String> = ChinaDate.getChinaDate(year, month, day)
|
||||||
|
// bean.chinaMonth = chinaDate[0]
|
||||||
|
// bean.chinaDay = chinaDate[1]
|
||||||
|
return bean
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,318 @@
|
|||||||
|
package com.example.accountbook.calendar
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import android.view.VelocityTracker
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewConfiguration
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.animation.Interpolator
|
||||||
|
import android.widget.AbsListView
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.ListView
|
||||||
|
import androidx.core.view.VelocityTrackerCompat
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.widget.ScrollerCompat
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
|
||||||
|
class CalendarLayout : FrameLayout {
|
||||||
|
private var view1: View? = null
|
||||||
|
// private var view2: ViewGroup? = null
|
||||||
|
private var mTopView: CalendarTopView? = null
|
||||||
|
var type = TYPE_OPEN
|
||||||
|
|
||||||
|
private var isSilde = false
|
||||||
|
private var topHeigth = 0
|
||||||
|
private var itemHeight = 0
|
||||||
|
private var bottomViewTopHeight = 0
|
||||||
|
private var maxDistance = 0
|
||||||
|
private var mScroller: ScrollerCompat? = null
|
||||||
|
private var mMaxVelocity = 0f
|
||||||
|
private var mMinVelocity = 0f
|
||||||
|
private var activitPotionerId = 0
|
||||||
|
|
||||||
|
constructor(context: Context?) : super(context!!) {
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(context: Context?, attrs: AttributeSet?) : super(
|
||||||
|
context!!, attrs
|
||||||
|
) {
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFinishInflate() {
|
||||||
|
super.onFinishInflate()
|
||||||
|
val viewPager: CalendarTopView = getChildAt(0) as CalendarTopView
|
||||||
|
mTopView = viewPager
|
||||||
|
view1 = viewPager as View
|
||||||
|
// view2 = getChildAt(1) as ViewGroup
|
||||||
|
mTopView?.setCalendarTopViewChangeListener(object: CalendarTopViewChangeListener {
|
||||||
|
override fun onLayoutChange(topView: CalendarTopView) {
|
||||||
|
requestLayout()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||||
|
itemHeight = mTopView?.itemHeight ?: 0
|
||||||
|
topHeigth = view1?.measuredHeight ?: 0
|
||||||
|
maxDistance = topHeigth - itemHeight
|
||||||
|
when (type) {
|
||||||
|
TYPE_FOLD -> bottomViewTopHeight = itemHeight
|
||||||
|
TYPE_OPEN -> bottomViewTopHeight = topHeigth
|
||||||
|
}
|
||||||
|
// view2!!.measure(
|
||||||
|
// widthMeasureSpec,
|
||||||
|
// MeasureSpec.makeMeasureSpec(
|
||||||
|
// MeasureSpec.getSize(heightMeasureSpec) - (mTopView?.itemHeight ?: 0),
|
||||||
|
// MeasureSpec.EXACTLY
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
|
||||||
|
super.onLayout(changed, left, top, right, bottom)
|
||||||
|
// view2!!.offsetTopAndBottom(bottomViewTopHeight)
|
||||||
|
val selectRct = selectRect
|
||||||
|
if (type == TYPE_FOLD) {
|
||||||
|
view1!!.offsetTopAndBottom(-selectRct[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun init() {
|
||||||
|
val vc = ViewConfiguration.get(context)
|
||||||
|
mMaxVelocity = vc.scaledMaximumFlingVelocity.toFloat()
|
||||||
|
mMinVelocity = vc.scaledMinimumFlingVelocity.toFloat()
|
||||||
|
mScroller = ScrollerCompat.create(context, sInterpolator)
|
||||||
|
}
|
||||||
|
|
||||||
|
var oy = 0f
|
||||||
|
var ox = 0f
|
||||||
|
var isClickBtottomView = false
|
||||||
|
// override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
|
||||||
|
//// mViewDragHelper.shouldInterceptTouchEvent(ev);
|
||||||
|
// var isflag = false
|
||||||
|
// when (ev.action) {
|
||||||
|
// MotionEvent.ACTION_DOWN -> {
|
||||||
|
// oy = ev.y
|
||||||
|
// ox = ev.x
|
||||||
|
// isClickBtottomView = isClickView(view2, ev)
|
||||||
|
// cancel()
|
||||||
|
// activitPotionerId = ev.getPointerId(0)
|
||||||
|
// val top = view2!!.top
|
||||||
|
// type = if (top < topHeigth) {
|
||||||
|
// TYPE_FOLD
|
||||||
|
// } else {
|
||||||
|
// TYPE_OPEN
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// MotionEvent.ACTION_MOVE -> {
|
||||||
|
// val y = ev.y
|
||||||
|
// val x = ev.x
|
||||||
|
// val xdiff = x - ox
|
||||||
|
// val ydiff = y - oy
|
||||||
|
// if (abs(ydiff.toDouble()) > 5 && abs(ydiff.toDouble()) > abs(xdiff.toDouble())) {
|
||||||
|
// isflag = true
|
||||||
|
// if (isClickBtottomView) {
|
||||||
|
// val isScroll = isScroll(view2)
|
||||||
|
// if (ydiff > 0) {
|
||||||
|
// //向下
|
||||||
|
// if (type == TYPE_OPEN) {
|
||||||
|
// return super.onInterceptTouchEvent(ev)
|
||||||
|
// } else {
|
||||||
|
// if (isScroll) {
|
||||||
|
// return super.onInterceptTouchEvent(ev)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// //向上
|
||||||
|
// if (type == TYPE_FOLD) {
|
||||||
|
// return super.onInterceptTouchEvent(ev)
|
||||||
|
// } else {
|
||||||
|
// if (isScroll) {
|
||||||
|
// return super.onInterceptTouchEvent(ev)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ox = x
|
||||||
|
// oy = y
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// MotionEvent.ACTION_UP -> {}
|
||||||
|
// }
|
||||||
|
// return isSilde || isflag || super.onInterceptTouchEvent(ev)
|
||||||
|
// }
|
||||||
|
|
||||||
|
private fun isScroll(view2: ViewGroup?): Boolean {
|
||||||
|
val fistChildView = view2!!.getChildAt(0) ?: return false
|
||||||
|
if (view2 is ListView) {
|
||||||
|
val list = view2 as AbsListView
|
||||||
|
if (fistChildView.top != 0) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
if (list.getPositionForView(fistChildView) != 0) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isClickView(view: View?, ev: MotionEvent): Boolean {
|
||||||
|
val rect = Rect()
|
||||||
|
view!!.getHitRect(rect)
|
||||||
|
val isClick = rect.contains(ev.x.toInt(), ev.y.toInt())
|
||||||
|
Log.d(
|
||||||
|
TAG,
|
||||||
|
"isClickView() called with: isClick = [$isClick]"
|
||||||
|
)
|
||||||
|
return isClick
|
||||||
|
}
|
||||||
|
|
||||||
|
// override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||||
|
// processTouchEvent(event)
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
|
||||||
|
private var mVelocityTracker: VelocityTracker? = null
|
||||||
|
// fun processTouchEvent(event: MotionEvent) {
|
||||||
|
// if (mVelocityTracker == null) {
|
||||||
|
// mVelocityTracker = VelocityTracker.obtain()
|
||||||
|
// }
|
||||||
|
// mVelocityTracker!!.addMovement(event)
|
||||||
|
// when (event.action) {
|
||||||
|
// MotionEvent.ACTION_DOWN -> {}
|
||||||
|
// MotionEvent.ACTION_MOVE -> {
|
||||||
|
// if (isSilde) {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// val cy = event.y
|
||||||
|
// val dy = (cy - oy).toInt()
|
||||||
|
// if (dy == 0) {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// oy = cy
|
||||||
|
// move(dy)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// MotionEvent.ACTION_UP -> {
|
||||||
|
// if (isSilde) {
|
||||||
|
// cancel()
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //判断速度
|
||||||
|
// val pointerId = activitPotionerId
|
||||||
|
// mVelocityTracker!!.computeCurrentVelocity(1000, mMaxVelocity)
|
||||||
|
// val crrentV = VelocityTrackerCompat.getYVelocity(mVelocityTracker, pointerId)
|
||||||
|
// if (abs(crrentV.toDouble()) > 2000) {
|
||||||
|
// if (crrentV > 0) {
|
||||||
|
// open()
|
||||||
|
// } else {
|
||||||
|
// flod()
|
||||||
|
// }
|
||||||
|
// cancel()
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// val top = view2!!.top - topHeigth
|
||||||
|
// val maxd = maxDistance
|
||||||
|
// if (abs(top.toDouble()) < maxd / 2) {
|
||||||
|
// open()
|
||||||
|
// } else {
|
||||||
|
// flod()
|
||||||
|
// }
|
||||||
|
// cancel()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// MotionEvent.ACTION_CANCEL -> cancel()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fun open() {
|
||||||
|
// startScroll(view2!!.top, topHeigth)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fun flod() {
|
||||||
|
// startScroll(view2!!.top, topHeigth - maxDistance)
|
||||||
|
// }
|
||||||
|
|
||||||
|
private val selectRect: IntArray
|
||||||
|
get() = mTopView?.currentSelectPositon ?: intArrayOf()
|
||||||
|
|
||||||
|
// private fun move(dy: Int) {
|
||||||
|
// val selectRect = selectRect
|
||||||
|
// val itemHeight: Int = mTopView?.itemHeight ?: 0
|
||||||
|
// val dy1 = getAreaValue(view1!!.top, dy, -selectRect[1], 0)
|
||||||
|
// val dy2 = getAreaValue(view2!!.top - topHeigth, dy, -(topHeigth - itemHeight), 0)
|
||||||
|
// if (dy1 != 0) {
|
||||||
|
// ViewCompat.offsetTopAndBottom(view1!!, dy1)
|
||||||
|
// }
|
||||||
|
// if (dy2 != 0) {
|
||||||
|
// ViewCompat.offsetTopAndBottom(view2!!, dy2)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
private fun getAreaValue(top: Int, dy: Int, minValue: Int, maxValue: Int): Int {
|
||||||
|
if (top + dy < minValue) {
|
||||||
|
return minValue - top
|
||||||
|
}
|
||||||
|
return if (top + dy > maxValue) {
|
||||||
|
maxValue - top
|
||||||
|
} else dy
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startScroll(starty: Int, endY: Int) {
|
||||||
|
val distance = (endY - starty).toFloat()
|
||||||
|
val t = distance / maxDistance * 600
|
||||||
|
mScroller!!.startScroll(0, 0, 0, endY - starty, abs(t.toDouble()).toInt())
|
||||||
|
postInvalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
var oldY = 0
|
||||||
|
// override fun computeScroll() {
|
||||||
|
// super.computeScroll()
|
||||||
|
// bottomViewTopHeight = view2!!.top
|
||||||
|
// if (mScroller!!.computeScrollOffset()) {
|
||||||
|
// isSilde = true
|
||||||
|
// val cy = mScroller!!.currY
|
||||||
|
// val dy = cy - oldY
|
||||||
|
// move(dy)
|
||||||
|
// oldY = cy
|
||||||
|
// postInvalidate()
|
||||||
|
// } else {
|
||||||
|
// oldY = 0
|
||||||
|
// isSilde = false
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
fun cancel() {
|
||||||
|
if (mVelocityTracker != null) {
|
||||||
|
mVelocityTracker!!.recycle()
|
||||||
|
mVelocityTracker = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "CalendarLayout"
|
||||||
|
|
||||||
|
const val TYPE_OPEN = 0
|
||||||
|
|
||||||
|
const val TYPE_FOLD = 1
|
||||||
|
private val sInterpolator: Interpolator = object: Interpolator {
|
||||||
|
override fun getInterpolation(t: Float): Float {
|
||||||
|
var t = t
|
||||||
|
t -= 1.0f
|
||||||
|
return t * t * t * t * t + 1.0f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.example.accountbook.calendar
|
||||||
|
|
||||||
|
|
||||||
|
interface CalendarTopView {
|
||||||
|
val currentSelectPositon: IntArray?
|
||||||
|
val itemHeight: Int
|
||||||
|
|
||||||
|
fun setCalendarTopViewChangeListener(listener: CalendarTopViewChangeListener?)
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package com.example.accountbook.calendar
|
||||||
|
|
||||||
|
interface CalendarTopViewChangeListener {
|
||||||
|
fun onLayoutChange(topView: CalendarTopView) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
package com.example.accountbook.calendar
|
||||||
|
|
||||||
|
import java.util.Calendar
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
|
||||||
|
object CalendarUtil {
|
||||||
|
fun getDayOfWeek(y: Int, m: Int, day: Int): Int {
|
||||||
|
val calendar: Calendar = Calendar.getInstance()
|
||||||
|
calendar.set(y, m - 1, day)
|
||||||
|
return calendar.get(Calendar.DAY_OF_WEEK)
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取一月最大天数
|
||||||
|
fun getDayOfMaonth(y: Int, m: Int): Int {
|
||||||
|
val cal: Calendar = Calendar.getInstance()
|
||||||
|
cal.set(y, m - 1, 1)
|
||||||
|
return cal.getActualMaximum(Calendar.DATE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getMothOfMonth(y: Int, m: Int): Int {
|
||||||
|
val cal: Calendar = Calendar.getInstance()
|
||||||
|
cal.set(y, m - 1, 1)
|
||||||
|
val dateOfMonth: Int = cal.get(Calendar.MONTH)
|
||||||
|
return dateOfMonth + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getYMD(date: Date?): IntArray {
|
||||||
|
val cal: Calendar = Calendar.getInstance()
|
||||||
|
date?.let { cal.setTime(it) }
|
||||||
|
return intArrayOf(
|
||||||
|
cal.get(Calendar.YEAR),
|
||||||
|
cal.get(Calendar.MONTH) + 1,
|
||||||
|
cal.get(Calendar.DATE)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,197 @@
|
|||||||
|
package com.example.accountbook.calendar
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.example.accountbook.calendar.CalendarUtil.getYMD
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
|
||||||
|
class CalendarView : ViewGroup {
|
||||||
|
private var selectPosition = -1
|
||||||
|
private var adapter: CalendarAdapter? = null
|
||||||
|
private var data: List<CalendarBean>? = null
|
||||||
|
private var onItemClickListener: OnItemClickListener? = null
|
||||||
|
private var row = 6
|
||||||
|
private val column = 7
|
||||||
|
private var itemWidth = 0
|
||||||
|
var itemHeight = 0
|
||||||
|
private set
|
||||||
|
private var isToday = false
|
||||||
|
|
||||||
|
interface OnItemClickListener {
|
||||||
|
fun onItemClick(view: View?, position: Int, bean: CalendarBean?)
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(context: Context?, row: Int) : super(context) {
|
||||||
|
this.row = row
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) {
|
||||||
|
this.onItemClickListener = onItemClickListener
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
||||||
|
setWillNotDraw(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setAdapter(adapter: CalendarAdapter?) {
|
||||||
|
this.adapter = adapter
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setData(data: List<CalendarBean>?, isToday: Boolean) {
|
||||||
|
this.data = data
|
||||||
|
this.isToday = isToday
|
||||||
|
setItem()
|
||||||
|
requestLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setItem() {
|
||||||
|
selectPosition = -1
|
||||||
|
if (adapter == null) {
|
||||||
|
throw RuntimeException("adapter is null,please setadapter")
|
||||||
|
}
|
||||||
|
Log.i("data >>> ","data ${data}")
|
||||||
|
if (adapter?.hasChildView() == true) {
|
||||||
|
for (i in data!!.indices) {
|
||||||
|
val bean = data!![i]
|
||||||
|
val chidView: View? = adapter?.getView(
|
||||||
|
getChildAt(i).also { v -> Log.i("data >>> ", "view $v") },
|
||||||
|
this,
|
||||||
|
bean
|
||||||
|
).also { v -> Log.i("data >>> ", "chidView $v") }
|
||||||
|
if (chidView != null && chidView != getChildAt(i)) {
|
||||||
|
addViewInLayout(chidView, i, chidView.layoutParams, true)
|
||||||
|
}
|
||||||
|
if (isToday && selectPosition == -1) {
|
||||||
|
val date = getYMD(Date())
|
||||||
|
if (bean.year == date[0] && bean.month == date[1] && bean.day == date[2]) {
|
||||||
|
selectPosition = i
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (selectPosition == -1 && bean.day == 1) {
|
||||||
|
selectPosition = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chidView?.isSelected = selectPosition == i
|
||||||
|
setItemClick(chidView, i, bean)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val select: Array<Any>
|
||||||
|
get() = arrayOf(
|
||||||
|
getChildAt(selectPosition), selectPosition,
|
||||||
|
data!![selectPosition]
|
||||||
|
)
|
||||||
|
|
||||||
|
fun setItemClick(view: View?, potsion: Int, bean: CalendarBean?) {
|
||||||
|
view?.setOnClickListener {
|
||||||
|
if (selectPosition != -1) {
|
||||||
|
getChildAt(selectPosition).isSelected = false
|
||||||
|
getChildAt(potsion).isSelected = true
|
||||||
|
}
|
||||||
|
selectPosition = potsion
|
||||||
|
if (onItemClickListener != null) {
|
||||||
|
onItemClickListener!!.onItemClick(view, potsion, bean)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSelectPosition(): IntArray {
|
||||||
|
val rect = Rect()
|
||||||
|
try {
|
||||||
|
getChildAt(selectPosition).getHitRect(rect)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
return intArrayOf(rect.left, rect.top, rect.right, rect.top)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var lastwidthMeasureSpec = 0
|
||||||
|
var lastheightMeasureSpec = 0
|
||||||
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||||
|
Log.e(this.javaClass::class.java.simpleName , "this count check ${this}")
|
||||||
|
if (widthMeasureSpec != lastwidthMeasureSpec || heightMeasureSpec != lastheightMeasureSpec) {
|
||||||
|
val parentWidth =
|
||||||
|
MeasureSpec.getSize(
|
||||||
|
MeasureSpec.makeMeasureSpec(
|
||||||
|
widthMeasureSpec,
|
||||||
|
MeasureSpec.EXACTLY
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val parentH =
|
||||||
|
MeasureSpec.getSize(
|
||||||
|
MeasureSpec.makeMeasureSpec(
|
||||||
|
heightMeasureSpec,
|
||||||
|
MeasureSpec.EXACTLY
|
||||||
|
)
|
||||||
|
)
|
||||||
|
itemWidth = parentWidth / column
|
||||||
|
itemHeight = parentH / row
|
||||||
|
// itemWidth
|
||||||
|
val view = getChildAt(0) ?: return
|
||||||
|
val params = view.layoutParams
|
||||||
|
if (params != null && params.height > 0) {
|
||||||
|
itemHeight = params.height
|
||||||
|
}
|
||||||
|
setMeasuredDimension(parentWidth, itemHeight * row)
|
||||||
|
if (childCount.equals(row*column))
|
||||||
|
for (i in 0 until childCount) {
|
||||||
|
val childView = getChildAt(i)
|
||||||
|
childView.measure(
|
||||||
|
MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY),
|
||||||
|
MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.i(
|
||||||
|
TAG,
|
||||||
|
"onMeasure() called with: itemHeight = [$itemHeight], itemWidth = [$itemWidth]"
|
||||||
|
)
|
||||||
|
lastwidthMeasureSpec = widthMeasureSpec
|
||||||
|
lastheightMeasureSpec = heightMeasureSpec
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
|
||||||
|
if (changed && childCount.equals(row*column))
|
||||||
|
for (i in 0 until childCount) {
|
||||||
|
layoutChild(getChildAt(i), i, l, t, r, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addViewInLayout(
|
||||||
|
child: View?,
|
||||||
|
index: Int,
|
||||||
|
params: LayoutParams?,
|
||||||
|
preventRequestLayout: Boolean
|
||||||
|
): Boolean {
|
||||||
|
Log.d("CalendarView, time","time")
|
||||||
|
return super.addViewInLayout(child, index, params, preventRequestLayout)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun layoutChild(view: View, position: Int, l: Int, t: Int, r: Int, b: Int) {
|
||||||
|
var l = l
|
||||||
|
var t = t
|
||||||
|
var r = r
|
||||||
|
var b = b
|
||||||
|
val cc = position % column
|
||||||
|
val cr = position / column
|
||||||
|
val itemWidth = view.measuredWidth
|
||||||
|
val itemHeight = view.measuredHeight
|
||||||
|
l = cc * itemWidth
|
||||||
|
t = cr * itemHeight
|
||||||
|
r = l + itemWidth
|
||||||
|
b = t + itemHeight
|
||||||
|
view.layout(l, t, r, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "CalendarView"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,113 @@
|
|||||||
|
package com.example.accountbook.fragment
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import com.example.accountbook.activity.ActivityWriter
|
||||||
|
import com.example.accountbook.calendar.CalendarAdapter
|
||||||
|
import com.example.accountbook.calendar.CalendarBean
|
||||||
|
import com.example.accountbook.databinding.FragmentCalendarBinding
|
||||||
|
import com.example.accountbook.databinding.ItemCalendarBinding
|
||||||
|
|
||||||
|
class FragmentCalendar: Fragment() {
|
||||||
|
private lateinit var bind: FragmentCalendarBinding
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
bind = FragmentCalendarBinding.inflate(inflater)
|
||||||
|
return bind.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
// init view
|
||||||
|
if (bind.calendarDateView.adapter == null) {
|
||||||
|
initView()
|
||||||
|
}
|
||||||
|
// init list
|
||||||
|
// initList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initView() {
|
||||||
|
Log.i("FragmentCalendar","initView")
|
||||||
|
|
||||||
|
bind.calendarDateView.setAdapter(object: CalendarAdapter {
|
||||||
|
override fun getView(
|
||||||
|
convertView: View?,
|
||||||
|
parentView: ViewGroup?,
|
||||||
|
bean: CalendarBean?
|
||||||
|
): View {
|
||||||
|
Log.i("FragmentCalendar","getView")
|
||||||
|
|
||||||
|
var bindItem : ItemCalendarBinding? = null
|
||||||
|
if (convertView == null) {
|
||||||
|
bindItem = ItemCalendarBinding.inflate(LayoutInflater.from(parentView?.context))
|
||||||
|
} else {
|
||||||
|
bindItem = ItemCalendarBinding.bind(convertView)
|
||||||
|
}
|
||||||
|
bindItem.day.apply {
|
||||||
|
this.text = bean?.day.toString()
|
||||||
|
if (bean?.monthFlag != 0) {
|
||||||
|
this.setTextColor(Color.WHITE)
|
||||||
|
} else {
|
||||||
|
this.setTextColor(Color.BLACK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bindItem.root.setOnLongClickListener{ it ->
|
||||||
|
startActivity(Intent(context, ActivityWriter::class.java))
|
||||||
|
return@setOnLongClickListener true
|
||||||
|
}
|
||||||
|
return convertView ?: bindItem.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hasChildView() = bind.calendarDateView.views.size > 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAttach(context: Context) {
|
||||||
|
super.onAttach(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
}
|
||||||
|
|
||||||
|
// private fun initList() {
|
||||||
|
// bind.list.setAdapter(object : BaseAdapter() {
|
||||||
|
// override fun getCount(): Int {
|
||||||
|
// Log.i("bindList" , "getCount ")
|
||||||
|
// return 100
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun getItem(position: Int) = null
|
||||||
|
//
|
||||||
|
// override fun getItemId(position: Int): Long = 0
|
||||||
|
//
|
||||||
|
// override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
|
||||||
|
// Log.i("bindList" , "getView ${position}")
|
||||||
|
// var mConvertView: View? = convertView
|
||||||
|
// if (mConvertView == null) {
|
||||||
|
// mConvertView = LayoutInflater.from(this@ActivityCalendar).inflate(android.R.layout.simple_list_item_1, null)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// (mConvertView as TextView).apply {
|
||||||
|
// this.text = "item" + position
|
||||||
|
// this.setBackgroundColor(Color.RED)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return mConvertView
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package com.example.accountbook.fragment
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import com.example.accountbook.R
|
||||||
|
import com.example.accountbook.adapter.AdapterTable
|
||||||
|
import com.example.accountbook.databinding.FragmentTableBinding
|
||||||
|
|
||||||
|
class FragmentTable: Fragment() {
|
||||||
|
private lateinit var bind: FragmentTableBinding
|
||||||
|
private var li: Array<String> = arrayOf("0", "1")
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
// view
|
||||||
|
bind = FragmentTableBinding.inflate(inflater)
|
||||||
|
// data
|
||||||
|
setData()
|
||||||
|
bind.listTable.adapter = AdapterTable(inflater.context, li)
|
||||||
|
return bind.root
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
170
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path
|
||||||
|
android:fillColor="#3DDC84"
|
||||||
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M9,0L9,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,0L19,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,0L29,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,0L39,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,0L49,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,0L59,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,0L69,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,0L79,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M89,0L89,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M99,0L99,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,9L108,9"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,19L108,19"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,29L108,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,39L108,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,49L108,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,59L108,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,69L108,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,79L108,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,89L108,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,99L108,99"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,29L89,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,39L89,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,49L89,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,59L89,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,69L89,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,79L89,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,19L29,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,19L39,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,19L49,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,19L59,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,19L69,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,19L79,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
</vector>
|
||||||
30
app/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="85.84757"
|
||||||
|
android:endY="92.4963"
|
||||||
|
android:startX="42.9492"
|
||||||
|
android:startY="49.59793"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0" />
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0" />
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:strokeColor="#00000000" />
|
||||||
|
</vector>
|
||||||
182
app/src/main/res/layout/activity_calendar.xml
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/activity_main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:background="#bbbbbb"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_weight="0">
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="월표시"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
/>
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/chk_shift"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="Shift"
|
||||||
|
/>
|
||||||
|
<!-- <Button-->
|
||||||
|
<!-- android:id="@+id/btn_shift"-->
|
||||||
|
<!-- android:layout_width="30dp"-->
|
||||||
|
<!-- android:layout_height="30dp"-->
|
||||||
|
<!-- android:text="전환"-->
|
||||||
|
<!-- android:layout_gravity="start|center_vertical"/>-->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_menu"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:text="메뉴"
|
||||||
|
android:layout_gravity="end|center_vertical"/>
|
||||||
|
</FrameLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:background="#cccccc"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="소득"
|
||||||
|
android:textColor="@color/black"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="10dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="+"
|
||||||
|
android:textColor="#ff0000"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="소득액"
|
||||||
|
android:textColor="#ff0000"/>
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:background="#cccccc"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="지출"
|
||||||
|
android:textColor="@color/black"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="10dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="-"
|
||||||
|
android:textColor="#0000ff"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="지출액"
|
||||||
|
android:textColor="#0000ff"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/fragment_box"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"/>
|
||||||
|
<!-- <LinearLayout-->
|
||||||
|
<!-- android:layout_width="match_parent"-->
|
||||||
|
<!-- android:layout_height="28dp"-->
|
||||||
|
<!-- android:orientation="horizontal"-->
|
||||||
|
<!-- android:background="#dddddd"-->
|
||||||
|
<!-- android:layout_weight="0">-->
|
||||||
|
<!-- <TextView-->
|
||||||
|
<!-- android:layout_width="0dp"-->
|
||||||
|
<!-- android:layout_height="match_parent"-->
|
||||||
|
<!-- android:layout_weight="1"-->
|
||||||
|
<!-- android:gravity="center"-->
|
||||||
|
<!-- android:text="일요일"-->
|
||||||
|
<!-- />-->
|
||||||
|
<!-- <TextView-->
|
||||||
|
<!-- android:layout_width="0dp"-->
|
||||||
|
<!-- android:layout_height="match_parent"-->
|
||||||
|
<!-- android:layout_weight="1"-->
|
||||||
|
<!-- android:gravity="center"-->
|
||||||
|
<!-- android:text="월요일"-->
|
||||||
|
<!-- />-->
|
||||||
|
<!-- <TextView-->
|
||||||
|
<!-- android:layout_width="0dp"-->
|
||||||
|
<!-- android:layout_height="match_parent"-->
|
||||||
|
<!-- android:layout_weight="1"-->
|
||||||
|
<!-- android:gravity="center"-->
|
||||||
|
<!-- android:text="화요일"-->
|
||||||
|
<!-- />-->
|
||||||
|
<!-- <TextView-->
|
||||||
|
<!-- android:layout_width="0dp"-->
|
||||||
|
<!-- android:layout_height="match_parent"-->
|
||||||
|
<!-- android:layout_weight="1"-->
|
||||||
|
<!-- android:gravity="center"-->
|
||||||
|
<!-- android:text="수요일"-->
|
||||||
|
<!-- />-->
|
||||||
|
<!-- <TextView-->
|
||||||
|
<!-- android:layout_width="0dp"-->
|
||||||
|
<!-- android:layout_height="match_parent"-->
|
||||||
|
<!-- android:layout_weight="1"-->
|
||||||
|
<!-- android:gravity="center"-->
|
||||||
|
<!-- android:text="목요일"-->
|
||||||
|
<!-- />-->
|
||||||
|
<!-- <TextView-->
|
||||||
|
<!-- android:layout_width="0dp"-->
|
||||||
|
<!-- android:layout_height="match_parent"-->
|
||||||
|
<!-- android:layout_weight="1"-->
|
||||||
|
<!-- android:gravity="center"-->
|
||||||
|
<!-- android:text="금요일"-->
|
||||||
|
<!-- />-->
|
||||||
|
<!-- <TextView-->
|
||||||
|
<!-- android:layout_width="0dp"-->
|
||||||
|
<!-- android:layout_height="match_parent"-->
|
||||||
|
<!-- android:layout_weight="1"-->
|
||||||
|
<!-- android:gravity="center"-->
|
||||||
|
<!-- android:text="토요일"-->
|
||||||
|
<!-- />-->
|
||||||
|
<!-- </LinearLayout>-->
|
||||||
|
|
||||||
|
<!-- <com.example.accountbook.calendar.CalendarLayout-->
|
||||||
|
<!-- android:layout_width="match_parent"-->
|
||||||
|
<!-- android:layout_height="0dp"-->
|
||||||
|
<!-- android:layout_weight="1"-->
|
||||||
|
<!-- android:background="#eeeeee"-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- <com.example.accountbook.calendar.CalendarDateView-->
|
||||||
|
<!-- android:id="@+id/calendarDateView"-->
|
||||||
|
<!-- android:background="#ddd000"-->
|
||||||
|
<!-- android:layout_width="match_parent"-->
|
||||||
|
<!-- android:layout_height="match_parent"/>-->
|
||||||
|
<!-- <ListView-->
|
||||||
|
<!-- android:id="@+id/list"-->
|
||||||
|
<!-- android:layout_width="match_parent"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:background="#ffffff"-->
|
||||||
|
<!-- />-->
|
||||||
|
<!-- </com.example.accountbook.calendar.CalendarLayout>-->
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
33
app/src/main/res/layout/activity_main.xml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<include layout="@layout/content_main" />
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/fab"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|end"
|
||||||
|
android:layout_marginEnd="@dimen/fab_margin"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
app:srcCompat="@android:drawable/ic_dialog_email" />
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
139
app/src/main/res/layout/activity_writer.xml
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:padding="20dp"
|
||||||
|
android:background="#aaaaaa">
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_write_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="2024.10.17"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingTop="20dp"
|
||||||
|
android:paddingBottom="20dp"
|
||||||
|
android:background="@color/white"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_write_close"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_marginEnd="12dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="close"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/text_write_title"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/text_write_title"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"/>
|
||||||
|
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/rg_write_addition_or_subtraction"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/text_write_title"
|
||||||
|
android:gravity="start|center_vertical"
|
||||||
|
android:background="@color/white">
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_write_addition"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:text="소득"/>
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rb_write_subtraction"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="지출"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:checked="true"/>
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
<TableLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/rg_write_addition_or_subtraction"
|
||||||
|
android:background="@color/white">
|
||||||
|
<TableRow
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:outlineProvider="bounds"
|
||||||
|
android:outlineSpotShadowColor="@color/white"
|
||||||
|
android:outlineAmbientShadowColor="@color/black"
|
||||||
|
android:elevation="10dp">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_write_subject_amount"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0.3"
|
||||||
|
android:text="금액"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#dddddd"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_write_amount"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0.7"
|
||||||
|
android:text="74,000"
|
||||||
|
android:gravity="end"
|
||||||
|
android:paddingEnd="20dp"/>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:outlineProvider="bounds"
|
||||||
|
android:outlineSpotShadowColor="@color/white"
|
||||||
|
android:outlineAmbientShadowColor="@color/black"
|
||||||
|
android:elevation="10dp">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_write_subject_category"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0.3"
|
||||||
|
android:text="카테고리"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#dddddd"/>
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/spinner_write_category"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0.7"
|
||||||
|
android:dropDownWidth="match_parent"
|
||||||
|
android:popupBackground="@color/white"
|
||||||
|
android:textAlignment="textEnd"/>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:outlineProvider="bounds"
|
||||||
|
android:outlineSpotShadowColor="@color/white"
|
||||||
|
android:outlineAmbientShadowColor="@color/black"
|
||||||
|
android:elevation="10dp">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_write_subject_memo"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0.3"
|
||||||
|
android:text="메모"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#dddddd"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_write_memo"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0.7"
|
||||||
|
android:text="커피"
|
||||||
|
android:gravity="end"
|
||||||
|
android:paddingEnd="20dp"/>
|
||||||
|
</TableRow>
|
||||||
|
</TableLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
19
app/src/main/res/layout/content_main.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/nav_host_fragment_content_main"
|
||||||
|
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:defaultNavHost="true"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:navGraph="@navigation/nav_graph" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
82
app/src/main/res/layout/fragment_calendar.xml
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="28dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:background="#dddddd"
|
||||||
|
android:layout_weight="0">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="일요일"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="월요일"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="화요일"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="수요일"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="목요일"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="금요일"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="토요일"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- <com.example.accountbook.calendar.CalendarLayout-->
|
||||||
|
<!-- android:layout_width="match_parent"-->
|
||||||
|
<!-- android:layout_height="0dp"-->
|
||||||
|
<!-- android:layout_weight="1"-->
|
||||||
|
<!-- android:background="#eeeeee"-->
|
||||||
|
<!-- >-->
|
||||||
|
<com.example.accountbook.calendar.CalendarDateView
|
||||||
|
android:id="@+id/calendarDateView"
|
||||||
|
android:background="#ddd000"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
<!-- <ListView-->
|
||||||
|
<!-- android:id="@+id/list"-->
|
||||||
|
<!-- android:layout_width="match_parent"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:background="#ffffff"-->
|
||||||
|
<!-- />-->
|
||||||
|
<!-- </com.example.accountbook.calendar.CalendarLayout>-->
|
||||||
|
</LinearLayout>
|
||||||
44
app/src/main/res/layout/fragment_first.xml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".FirstFragment">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<!-- <Button-->
|
||||||
|
<!-- android:id="@+id/button_first"-->
|
||||||
|
<!-- android:layout_width="wrap_content"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:text="@string/showing_detail"-->
|
||||||
|
<!-- app:layout_constraintBottom_toTopOf="@id/view_calendar"-->
|
||||||
|
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||||
|
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||||
|
<!-- app:layout_constraintTop_toTopOf="parent" />-->
|
||||||
|
|
||||||
|
<!-- <CalendarView-->
|
||||||
|
<!-- android:id="@+id/view_calendar"-->
|
||||||
|
<!-- android:layout_width="wrap_content"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:layout_marginTop="16dp"-->
|
||||||
|
<!-- app:layout_constraintTop_toBottomOf="@id/button_first"-->
|
||||||
|
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||||
|
<!-- app:layout_constraintEnd_toEndOf="parent" />-->
|
||||||
|
|
||||||
|
<!-- <TextView-->
|
||||||
|
<!-- android:id="@+id/textview_first"-->
|
||||||
|
<!-- android:layout_width="wrap_content"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:layout_marginTop="16dp"-->
|
||||||
|
<!-- android:text="@string/lorem_ipsum"-->
|
||||||
|
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
|
||||||
|
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||||
|
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||||
|
<!-- app:layout_constraintTop_toBottomOf="@id/button_first" />-->
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
35
app/src/main/res/layout/fragment_second.xml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".SecondFragment">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/button_second"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/showing_home"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/textview_second"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textview_second"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/lorem_ipsum"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/button_second" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
44
app/src/main/res/layout/fragment_table.xml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TableLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#33ee33">
|
||||||
|
<TableRow
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="30dp">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.1"
|
||||||
|
android:text="날짜"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#eeeeee"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.3"
|
||||||
|
android:text="금액"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#dddddd"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.5"
|
||||||
|
android:text="메모"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#eeeeee"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.2"
|
||||||
|
android:text="카테고리"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#dddddd"/>
|
||||||
|
</TableRow>
|
||||||
|
<ListView
|
||||||
|
android:id="@+id/list_table"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"/>
|
||||||
|
</TableLayout>
|
||||||
54
app/src/main/res/layout/item_calendar.xml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/day"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="날짜"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_plus"
|
||||||
|
android:layout_width="10dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="+"
|
||||||
|
android:textColor="#ff0000"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/day"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="당일소득"
|
||||||
|
android:textColor="#ff0000"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/text_plus"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/text_plus"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/text_plus"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_minus"
|
||||||
|
android:layout_width="10dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="-"
|
||||||
|
android:textColor="#0000ff"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/text_plus"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="당일지출"
|
||||||
|
android:textColor="#0000ff"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/text_minus"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/text_minus"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/text_minus"/>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
9
app/src/main/res/layout/item_spinner_writer_category.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="기타"
|
||||||
|
android:gravity="end"
|
||||||
|
/>
|
||||||
37
app/src/main/res/layout/item_table.xml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_date"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.1"
|
||||||
|
android:text="date"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#eeeeee"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_amount"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.3"
|
||||||
|
android:text="amount"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#dddddd"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_memo"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.5"
|
||||||
|
android:text="memo"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#eeeeee"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_category"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.2"
|
||||||
|
android:text="category"
|
||||||
|
android:gravity="center"
|
||||||
|
android:background="#dddddd"/>
|
||||||
|
</TableRow>
|
||||||
10
app/src/main/res/menu/menu_main.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
tools:context="com.example.accountbook.MainActivity">
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_settings"
|
||||||
|
android:orderInCategory="100"
|
||||||
|
android:title="@string/action_settings"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
</menu>
|
||||||
6
app/src/main/res/mipmap-anydpi/ic_launcher.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
||||||
6
app/src/main/res/mipmap-anydpi/ic_launcher_round.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
||||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 982 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
28
app/src/main/res/navigation/nav_graph.xml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/nav_graph"
|
||||||
|
app:startDestination="@id/FirstFragment">
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/FirstFragment"
|
||||||
|
android:name="com.example.accountbook.FirstFragment"
|
||||||
|
android:label="@string/first_fragment_label"
|
||||||
|
tools:layout="@layout/fragment_first">
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_FirstFragment_to_SecondFragment"
|
||||||
|
app:destination="@id/SecondFragment" />
|
||||||
|
</fragment>
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/SecondFragment"
|
||||||
|
android:name="com.example.accountbook.SecondFragment"
|
||||||
|
android:label="@string/second_fragment_label"
|
||||||
|
tools:layout="@layout/fragment_second">
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_SecondFragment_to_FirstFragment"
|
||||||
|
app:destination="@id/FirstFragment" />
|
||||||
|
</fragment>
|
||||||
|
</navigation>
|
||||||
3
app/src/main/res/values-land/dimens.xml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<dimen name="fab_margin">48dp</dimen>
|
||||||
|
</resources>
|
||||||
7
app/src/main/res/values-night/themes.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="Base.Theme.AccountBook" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
|
<!-- Customize your dark theme here. -->
|
||||||
|
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
9
app/src/main/res/values-v23/themes.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<style name="Theme.AccountBook" parent="Base.Theme.AccountBook">
|
||||||
|
<!-- Transparent system bars for edge-to-edge. -->
|
||||||
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
<item name="android:windowLightStatusBar">?attr/isLightTheme</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
3
app/src/main/res/values-w1240dp/dimens.xml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<dimen name="fab_margin">200dp</dimen>
|
||||||
|
</resources>
|
||||||
3
app/src/main/res/values-w600dp/dimens.xml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<dimen name="fab_margin">48dp</dimen>
|
||||||
|
</resources>
|
||||||
9
app/src/main/res/values/attr.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<attr name="cbd_calendar_row" format="integer"/>
|
||||||
|
|
||||||
|
<declare-styleable name="CalendarDateView">
|
||||||
|
<attr name="cbd_calendar_row"/>
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
</resources>
|
||||||
5
app/src/main/res/values/colors.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="black">#FF000000</color>
|
||||||
|
<color name="white">#FFFFFFFF</color>
|
||||||
|
</resources>
|
||||||
3
app/src/main/res/values/dimens.xml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<dimen name="fab_margin">16dp</dimen>
|
||||||
|
</resources>
|
||||||
46
app/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">AccountBook</string>
|
||||||
|
<string name="action_settings">Settings</string>
|
||||||
|
<!-- Strings used for fragments for navigation -->
|
||||||
|
<string name="first_fragment_label">First Fragment</string>
|
||||||
|
<string name="second_fragment_label">Second Fragment</string>
|
||||||
|
<string name="showing_detail">상세 보기</string>
|
||||||
|
<string name="showing_home">홈으로</string>
|
||||||
|
|
||||||
|
<string name="lorem_ipsum">
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris
|
||||||
|
volutpat, dolor id interdum ullamcorper, risus dolor egestas lectus, sit amet mattis purus
|
||||||
|
dui nec risus. Maecenas non sodales nisi, vel dictum dolor. Class aptent taciti sociosqu ad
|
||||||
|
litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse blandit eleifend
|
||||||
|
diam, vel rutrum tellus vulputate quis. Aliquam eget libero aliquet, imperdiet nisl a,
|
||||||
|
ornare ex. Sed rhoncus est ut libero porta lobortis. Fusce in dictum tellus.\n\n
|
||||||
|
Suspendisse interdum ornare ante. Aliquam nec cursus lorem. Morbi id magna felis. Vivamus
|
||||||
|
egestas, est a condimentum egestas, turpis nisl iaculis ipsum, in dictum tellus dolor sed
|
||||||
|
neque. Morbi tellus erat, dapibus ut sem a, iaculis tincidunt dui. Interdum et malesuada
|
||||||
|
fames ac ante ipsum primis in faucibus. Curabitur et eros porttitor, ultricies urna vitae,
|
||||||
|
molestie nibh. Phasellus at commodo eros, non aliquet metus. Sed maximus nisl nec dolor
|
||||||
|
bibendum, vel congue leo egestas.\n\n
|
||||||
|
Sed interdum tortor nibh, in sagittis risus mollis quis. Curabitur mi odio, condimentum sit
|
||||||
|
amet auctor at, mollis non turpis. Nullam pretium libero vestibulum, finibus orci vel,
|
||||||
|
molestie quam. Fusce blandit tincidunt nulla, quis sollicitudin libero facilisis et. Integer
|
||||||
|
interdum nunc ligula, et fermentum metus hendrerit id. Vestibulum lectus felis, dictum at
|
||||||
|
lacinia sit amet, tristique id quam. Cras eu consequat dui. Suspendisse sodales nunc ligula,
|
||||||
|
in lobortis sem porta sed. Integer id ultrices magna, in luctus elit. Sed a pellentesque
|
||||||
|
est.\n\n
|
||||||
|
Aenean nunc velit, lacinia sed dolor sed, ultrices viverra nulla. Etiam a venenatis nibh.
|
||||||
|
Morbi laoreet, tortor sed facilisis varius, nibh orci rhoncus nulla, id elementum leo dui
|
||||||
|
non lorem. Nam mollis ipsum quis auctor varius. Quisque elementum eu libero sed commodo. In
|
||||||
|
eros nisl, imperdiet vel imperdiet et, scelerisque a mauris. Pellentesque varius ex nunc,
|
||||||
|
quis imperdiet eros placerat ac. Duis finibus orci et est auctor tincidunt. Sed non viverra
|
||||||
|
ipsum. Nunc quis augue egestas, cursus lorem at, molestie sem. Morbi a consectetur ipsum, a
|
||||||
|
placerat diam. Etiam vulputate dignissim convallis. Integer faucibus mauris sit amet finibus
|
||||||
|
convallis.\n\n
|
||||||
|
Phasellus in aliquet mi. Pellentesque habitant morbi tristique senectus et netus et
|
||||||
|
malesuada fames ac turpis egestas. In volutpat arcu ut felis sagittis, in finibus massa
|
||||||
|
gravida. Pellentesque id tellus orci. Integer dictum, lorem sed efficitur ullamcorper,
|
||||||
|
libero justo consectetur ipsum, in mollis nisl ex sed nisl. Donec maximus ullamcorper
|
||||||
|
sodales. Praesent bibendum rhoncus tellus nec feugiat. In a ornare nulla. Donec rhoncus
|
||||||
|
libero vel nunc consequat, quis tincidunt nisl eleifend. Cras bibendum enim a justo luctus
|
||||||
|
vestibulum. Fusce dictum libero quis erat maximus, vitae volutpat diam dignissim.
|
||||||
|
</string>
|
||||||
|
</resources>
|
||||||
9
app/src/main/res/values/themes.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="Base.Theme.AccountBook" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
|
<!-- Customize your light theme here. -->
|
||||||
|
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.AccountBook" parent="Base.Theme.AccountBook" />
|
||||||
|
</resources>
|
||||||
13
app/src/main/res/xml/backup_rules.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
Sample backup rules file; uncomment and customize as necessary.
|
||||||
|
See https://developer.android.com/guide/topics/data/autobackup
|
||||||
|
for details.
|
||||||
|
Note: This file is ignored for devices older that API 31
|
||||||
|
See https://developer.android.com/about/versions/12/backup-restore
|
||||||
|
-->
|
||||||
|
<full-backup-content>
|
||||||
|
<!--
|
||||||
|
<include domain="sharedpref" path="."/>
|
||||||
|
<exclude domain="sharedpref" path="device.xml"/>
|
||||||
|
-->
|
||||||
|
</full-backup-content>
|
||||||
19
app/src/main/res/xml/data_extraction_rules.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
Sample data extraction rules file; uncomment and customize as necessary.
|
||||||
|
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
|
||||||
|
for details.
|
||||||
|
-->
|
||||||
|
<data-extraction-rules>
|
||||||
|
<cloud-backup>
|
||||||
|
<!-- TODO: Use <include> and <exclude> to control what is backed up.
|
||||||
|
<include .../>
|
||||||
|
<exclude .../>
|
||||||
|
-->
|
||||||
|
</cloud-backup>
|
||||||
|
<!--
|
||||||
|
<device-transfer>
|
||||||
|
<include .../>
|
||||||
|
<exclude .../>
|
||||||
|
</device-transfer>
|
||||||
|
-->
|
||||||
|
</data-extraction-rules>
|
||||||
17
app/src/test/java/com/example/accountbook/ExampleUnitTest.kt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package com.example.accountbook
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
class ExampleUnitTest {
|
||||||
|
@Test
|
||||||
|
fun addition_isCorrect() {
|
||||||
|
assertEquals(4, 2 + 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
15
build.gradle.kts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
plugins {
|
||||||
|
alias(libs.plugins.androidApplication) apply false
|
||||||
|
alias(libs.plugins.jetbrainsKotlinAndroid) apply false
|
||||||
|
}
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
google()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath("com.jakewharton:butterknife-gradle-plugin:10.2.3")
|
||||||
|
}
|
||||||
|
}
|
||||||
23
gradle.properties
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Project-wide Gradle settings.
|
||||||
|
# IDE (e.g. Android Studio) users:
|
||||||
|
# Gradle settings configured through the IDE *will override*
|
||||||
|
# any settings specified in this file.
|
||||||
|
# For more details on how to configure your build environment visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||||
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
# This option should only be used with decoupled projects. For more details, visit
|
||||||
|
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
|
||||||
|
# org.gradle.parallel=true
|
||||||
|
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||||
|
# Android operating system, and which are packaged with your app's APK
|
||||||
|
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||||
|
android.useAndroidX=true
|
||||||
|
# Kotlin code style for this project: "official" or "obsolete":
|
||||||
|
kotlin.code.style=official
|
||||||
|
# Enables namespacing of each library's R class so that its R class includes only the
|
||||||
|
# resources declared in the library itself and none from the library's dependencies,
|
||||||
|
# thereby reducing the size of the R class for that library
|
||||||
|
android.nonTransitiveRClass=true
|
||||||
89
gradlew.bat
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
||||||
24
settings.gradle.kts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
google {
|
||||||
|
content {
|
||||||
|
includeGroupByRegex("com\\.android.*")
|
||||||
|
includeGroupByRegex("com\\.google.*")
|
||||||
|
includeGroupByRegex("androidx.*")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dependencyResolutionManagement {
|
||||||
|
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rootProject.name = "AccountBook"
|
||||||
|
include(":app")
|
||||||
|
|
||||||