diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -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 diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..b3405b3 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +My Application \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..fb7f4a8 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..f57f977 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..526b4c2 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..3be77b4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 95b0ff1..0000000 --- a/README.md +++ /dev/null @@ -1,690 +0,0 @@ -# Android-Hyebin -![github_이혜빈_ver1-25](https://user-images.githubusercontent.com/70698151/135754518-b0b65ab0-5cd6-45e6-8ce9-4b307a36e278.png) - -


-# 1️⃣ First Week - -|SignIn|Login|Home|SignUp| -|---|---|---|---| -|![ezgif com-gif-maker](https://user-images.githubusercontent.com/69586104/136684197-a3f800e8-0c45-408a-b972-aa521b508674.gif)|![ezgif com-gif-maker (1)](https://user-images.githubusercontent.com/69586104/136684208-af155ede-b430-47ca-994f-2ed212b1c3a8.gif)|![ezgif com-gif-maker (2)](https://user-images.githubusercontent.com/69586104/136684214-f2df8ce7-8333-44b0-ba88-6172f70f663b.gif)|![ezgif com-gif-maker (3)](https://user-images.githubusercontent.com/69586104/136684221-7a219180-a466-4135-806b-fa699022ff02.gif)| - - -


- -**1. SignUp** - + 아이디, 비밀번호 입력이 모두 되었을 때만 로그인 버튼 눌렀을 때 HomeActivity로 이동 (토스트메시지 출력) - -```kotlin -val intentHome = Intent(this, HomeActivity::class.java) - -binding.apply { - btnLogin.setOnClickListener { - val userId : String = etId.text.toString() - val userPw : String = etPassword.text.toString() - if (userId.isNotEmpty() && userPw.isNotEmpty()) { - startActivity(intentHome) - Toast.makeText(this@SignInActivity, "$userId 님 환영합니다", Toast.LENGTH_SHORT).show() - } else { - Toast.makeText(this@SignInActivity, "로그인 실패", Toast.LENGTH_SHORT).show() - } - } - } -``` - -

- + 회원가입 버튼 눌렀을 때 화면 이동 - -```kotlin -val intentSingUp = Intent(this, SignUpActivity::class.java) - -btnSignup.setOnClickListener { - startActivity(intentSingUp) - finish() -} -``` - -

- + 회원가입에 성공한 뒤, 아이디&패스워드 자동 입력 - -```kotlin -if (intent.hasExtra("id") && intent.hasExtra("pw")) { - val id = intent.getStringExtra("id") - val pw = intent.getStringExtra("pw") - - etId.setText(id) - etPassword.setText(pw) -} -``` - -

- - + EditText의 hint 속성 및 비밀번호의 inputType 속성 - - -```kotlin - -``` -


- -**2. Home** - + Home 버튼 누르면 나의 git 페이지로 이동 (암시적 인텐트) -```kotlin -binding.btnGit.setOnClickListener{ - var intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/lhb8106")) - startActivity(intent) -} -``` -
- -**✅명시적 인텐트와 암시적 인텐트의 차이점✅** -

-명시적 인텐트는 실행하고자하는 컴포넌트가 명확할 때 사용하는 방식입니다. 즉, 패키지 내부의 액티비티를 실행할 때 사용됩니다.
-암시적 인텐트는 어떠한 인텐트를 담아서 보내면, 시스템이 적절한 컴포넌트를 찾아서 실행해주는 방식입니다. - -

- - + 사진 비율 맞추기 -```kotlin - -``` -

- - + 스크롤뷰 적용 -```kotlin - - -``` -


- -**3. SignIn** - + 회원가입 완료 버튼 눌렀을 때, 빈칸 확인 및 아이디, 비밀번호 값 넘겨주기 -```kotlin -val intent = Intent(this, SignInActivity::class.java) - -binding.apply { - btnSingup.setOnClickListener { - val userName : String = etName.text.toString() - val userId : String = etId.text.toString() - val userPw : String = etPassword.text.toString() - - if (userName.isNotEmpty() && userId.isNotEmpty() && userPw.trim().isNotEmpty()) { - intent.putExtra("id", userId) - intent.putExtra("pw", userPw) - startActivity(intent) - finish() - - } else { - Toast.makeText(this@SignUpActivity, "입력되지 않은 정보가 있습니다", Toast.LENGTH_SHORT).show() - } - } - } -``` - -

- + hint 속성 및 inputType 속성은 위의 SignUp과 같습니다. - -



-*** -
- -**🤍이번 과제를 통해 배운 내용 & 성장한 내용🤍** - -
-**☝constraintlayout을 정확히 이해했습니다!** -
-지금까지 안드로이드 스튜디오에서 LinearLayout을 주로 사용하고, ConstraintLayout을 제대로 활용해본 경험이 없었는데, -이번 과제와 세미나를 통해 ConstraintLayout을 제대로 이해하고 활용할 수 있는 방법을 알게 되었습니다. -
-그 외에도 layout 내에서 쓸 수 있는 다양한 속성을 익힐 수 있었습니다. (inputType 속성 & constraintDimensionRatio 속성) -

- -**✌intent를 이해할 수 있는 기회가 되었습니다!** -
-처음에는 잘 이해가 되지 않았지만, 여러번 화면을 이동하는 연습을 하다보니, intent를 사용하는 방법과 활용 방안에 대해서 잘 익힐 수 있는 기회가 되었습니다. -
-하지만 hasExtra는 아직은..잘 모르겠네요.. 얼렁뚱당 의도대로 움직이긴 하지만 더 정확한 코드를 작성하고 싶습니다. -

- -**👌git과 notion** -
-git을 다루는 방법을 하나도 모르는 사람이었는데, 이번에 과제를 제출하기 위해 유튜브도 찾아보고 많은 사람들에게 물어보며 공부를 했습니다..
-아직 배워야할 점이 산더미이지만 차근차근 올라가서 나중에는 꼭 깃 마스터가 되겠습니다..❗
-그리고 notion을 솝트 들어와서 처음 알게 되었다보니, 자료 하나 찾는데에도 꽤 많은 시간을 소모했습니다.
-하지만 자주 들어가서 정보를 확인하다보니 notion이 점점 어렵지 않게 느껴집니다!
-노션과 깃.. 차차 친해지겠습니다💗 -


- - - -




- -# 2️⃣ Second Week - -|Home| -|---| -|![ezgif com-gif-maker (5)](https://user-images.githubusercontent.com/69586104/138444148-fa9b689b-10ec-4559-ba0c-3bf935d4707f.gif)| - - -

- - -🙏FollowerRecyclerView와 RepositoryRecyclerView의 코드가 유사하므로 FollowerRecyclerView 구현코드만 작성하겠습니다.🙏 - -
- -## LEVEL1 - -

- -**1. FollowerRecyclerView** - - -+) LinearLayoutManager 사용 ( GridLayoutManage관련 코드는 하단에 첨부하겠습니다. ) - -```kotlin - -``` - -

- -**2. FolloweData** - -```kotlin -data class FollowerData( - val name: String, - val introduction: String -) -``` - -

- -**3. FollowrAdapter** - -```kotlin -class FollowerAdapter : RecyclerView.Adapter() { - val userList = mutableListOf() - - class FollowerViewHolder(private val binding : ItemFollowerListBinding) : RecyclerView.ViewHolder(binding.root){ - fun onBind(data: FollowerData) { - binding.tvName.text = data.name - binding.tvIntroduction.text = data.introduction - } - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FollowerViewHolder { - val binding = ItemFollowerListBinding.inflate(LayoutInflater.from(parent.context),parent,false) - - return FollowerViewHolder(binding) - } - - override fun onBindViewHolder(holder: FollowerViewHolder, position: Int) { - holder.onBind(userList[position]) - } - - override fun getItemCount(): Int = userList.size -} - -``` - -

- - - -**FollowerFragment** - -```kotlin -class FollowerFragment : Fragment() { - private lateinit var follwerAdapter: FollowerAdapter - private var _binding: FollowerFragmentBinding? = null - private val binding get() = _binding!! - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - _binding = FollowerFragmentBinding.inflate(layoutInflater, container,false) - - follwerAdapter = FollowerAdapter() - binding.rvFollower.adapter = follwerAdapter - - follwerAdapter.userList.addAll( - listOf( - FollowerData("이혜빈1", "안녕하세요"), - FollowerData("이혜빈2", "안녕하세요"), - FollowerData("이혜빈3", "안녕하세요"), - FollowerData("이혜빈4", "안녕하세요") - ) - ) - follwerAdapter.notifyDataSetChanged() - return binding.root - - } - - override fun onDestroy() { - super.onDestroy() - _binding = null - } -} -``` - -

- -**HomeActivity** - -```kotlin -class HomeActivity : AppCompatActivity() { - private var postion = FIRST_POSITION - private lateinit var binding : ActivityHomeBinding - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = ActivityHomeBinding.inflate(layoutInflater) - - setContentView(binding.root) - - initTransactionEvent() - } - - fun initTransactionEvent() { - val followerFragment = FollowerFragment() - val repositstoryFragment = RepositoryFragment() - - supportFragmentManager.beginTransaction().add(R.id.container_rv, followerFragment).commit() - - binding.btnFollower.setOnClickListener { - supportFragmentManager.beginTransaction().replace(R.id.container_rv, followerFragment) .commit() - } - - binding.btnRepository.setOnClickListener { - supportFragmentManager.beginTransaction().replace(R.id.container_rv, repositstoryFragment) .commit() - } - } - - - companion object { - const val FIRST_POSITION = 1 - } - -} -``` - -

- - -**xml ellipsize 속성** -```kotlin - -``` - -

- -**RepositoryRecyclerView 속성** -
-+)GridlayoutManager 사용 - -```kotlin - - -``` - -
- -## LEVEL2-2 - -
-시험기간이라.. 2-2만 구현했습니다.. 다른 부분은 차차 해보겠습니다... - -

- -**Decoration** - -```kotlin - class Decoration(val colorString: String, val left: Int, val right: Int, val height: Int, val bottom:Int) : RecyclerView.ItemDecoration() { - override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { - super.onDraw(c, parent, state) - - val paint = Paint().apply { - color = Color.parseColor(colorString) - } - - for (i in 0 until parent.childCount) { - val child = parent.getChildAt(i) - if (i != parent.childCount - 1) { - c.drawRect(child.left.toFloat(), child.bottom.toFloat(), child.right.toFloat(), child.bottom.toFloat() + height, paint) - } - } - } - override fun getItemOffsets( - outRect: Rect, - view: View, - parent: RecyclerView, - state: RecyclerView.State - ) { - super.getItemOffsets(outRect, view, parent, state) - outRect.right = right - outRect.left = left - outRect.top = height - outRect.bottom = height - } -} - -``` -

- -**FollowerFragment** - -```kotlin -binding.rvFollower.addItemDecoration(Decoration("#F658A6", 50,50,25,25)) -``` - -



-*** -
- -**🤍이번 과제를 통해 배운 내용 & 성장한 내용🤍** - -
- -**☝Fragment에 대해 이해했습니다.** -
-실습 예제만 따라하고 직접 원하는 요소를 살려서 구현은 해본 적이 없었는데, 이번 기회를 통해 직접 코드를 작성하면서 제대로 이해할 수 있는 시간을 가졌습니다. -
-그리고 fragment에서 binding을 사용하는 법 또한 익힐 수 있었습니다. 생명주기를 제대로 이해하지 못했는데 이번 기회를 통해 제대로 이해할 수 있게 되었습니다. -

- -**✌ItemDecoration을 알게 되었습니다.** -
-원래 xml에서 margin값을 모두 줬는데, 이번 과제를 통해 ItemDecoration을 처음 알게되었습니다. -
-그래서 제가봐도 아직 부족하고.. 이상한.. 코드지만 더 열심히 공부해서.. 다음주에 더 나은 코드로 바꿔오겠습니다 - -


- -




- -# 3️⃣ Third Week - -|SignUp|SignIn|Profile|Home|ViewPager| -|---|---|---|---|---| -|![ezgif com-gif-maker (6)](https://user-images.githubusercontent.com/69586104/139569164-e49e2022-49ec-44a1-a9c9-175248f5ae29.gif)| ![ezgif com-gif-maker (7)](https://user-images.githubusercontent.com/69586104/139569185-bf83c8f8-820f-4b66-b505-592578b36859.gif)|![ezgif com-gif-maker (8)](https://user-images.githubusercontent.com/69586104/139569193-df9a7f96-64d3-4962-8bae-140a659571a7.gif)|![ezgif com-gif-maker (9)](https://user-images.githubusercontent.com/69586104/139569199-8367e45a-faca-4e24-9049-e147d65f724a.gif)|![ezgif com-gif-maker (10)](https://user-images.githubusercontent.com/69586104/139569210-96a0630e-680b-494c-a4a3-dadb42c389fc.gif)| - - -

- -## LEVEL1 - -

- -**1-1. EditText에 selector 활용하기** - - -```kotlin - - - - -``` - -

- -**1-2. 버튼 등등 Drawable로 직접 만들기** - -```kotlin - - - -``` - -

- -✍Button에 selector 활용하기는 위의 EditText에 selector 활용하기와 같은 방식으로 코드를 작성했습니다! - -
- -**2-1. 이미지 Glide의 CircleCrop 기능을 활용해서 넣어주기** - -```kotlin - Glide.with(this) - .load("https://mblogthumb-phinf.pstatic.net/MjAxOTA0MjNfMjcy/MDAxNTU2MDIwNjg0ODMw.KwUiIDMhdpKzsuNX83GpdFljS1HjgNhCBNcXv2QXfxkg.ksHQVjDUTn8AMV4XVSfETLX-tZ1LTz9-bOmO0o7AtI8g.JPEG.ndh7782/%EC%B9%98%EC%A6%8801.JPG?type=w800") - .apply(RequestOptions.circleCropTransform()) - .into(binding.ivProfile) - -``` - -

- - - -**2-2. 아이콘 이미지 export해서 사용** - -```kotlin - - - - - - - -``` - -

- -**2-3. 하단에 BottomNavigation 넣어주기** - -```kotlin - -``` - -

- - -**xml ellipsize 속성** -```kotlin - -``` - -

- -**3-1 TabLayout + ViewPager2** - -```kotlin - - - - - - -``` - -
- -## LEVEL2-2 - -

- -**FollowerAdapter** - -```kotlin - Glide.with(itemView.context).load(data.photo) - .apply(RequestOptions.circleCropTransform()) - .into(binding.ivProfile) -``` -

- -**FollowerData** - -```kotlin -data class FollowerData( - val name: String, - val introduction: String, - val photo : String -) -``` - -

- -**FollowerFragment** - -```kotlin - follwerAdapter.userList.addAll( - listOf( - FollowerData("스폰지밥", "안녕하세요", "https://ww.namu.la/s/bd52223e4d1f11fcc4c7f6506bf3321b26579bf118db6c1ca20492b9af4228a414edd25f1006baace220e4ca771288e0f38d6cbf253ae4e9d39aaf4b881600b0d65e518e7d94891837ee9a0c6a723aac0f4d2b7bf4a65b36bd1fe636aa49c632"), - FollowerData("뚱이", "안녕하세요", "https://img.insight.co.kr/static/2020/08/12/700/fyzvinle3b068ce501hq.jpg"), - FollowerData("집게사장", "안녕하세요", "https://pbs.twimg.com/media/D8RITHlV4AAb1iG.jpg") - ) - ) -``` - - -



-*** -
- -**🤍이번 과제를 통해 배운 내용 & 성장한 내용🤍** - -
- -**☝디자인을 적용하는 방법을 익혔습니다** -
-초기에 직접 레이아웃을 짰을 때와 디자이너분께서 디자인해주는 것을 보며 수정을 해나가면서 나오는 결과물의 차이를 보고 디자이너의 중요성과 협업의 중요성을 깨달을 수 있는 계가기 되었습니다. -
-또한, 피그마를 제대로 다뤄본 적이 한번도 없었는데, 협업에 있어서 피그마를 쓰는 법을 익힐 수 있었습니다. -

- -**✌ViewPager2를 이해했습니다** -
-어플을 사용하면서 가장 많이 봤던 기능 중 하나였는데, 이번 세미나를 통해 ViewPager2를 알 수 있었습니다. -
-또한, TabLayout등등도 함께 배울 수 있어서 뜻깊었습니다. - -


- diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..8b06cbb --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,56 @@ +plugins { + id 'com.android.application' + id 'kotlin-android' +} + +android { + compileSdk 30 + + defaultConfig { + applicationId "com.example.myapplication" + minSdk 26 + targetSdk 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + buildFeatures { + viewBinding true + } + } + + buildTypes { + release { + minifyEnabled 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' + } +} + +dependencies { + implementation "com.squareup.retrofit2:retrofit:2.9.0" + implementation "com.squareup.retrofit2:converter-gson:2.9.0" + implementation "com.google.code.gson:gson:2.8.6" + + implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' + implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' + + implementation 'androidx.core:core-ktx:1.6.0' + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'com.google.android.material:material:1.4.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.1' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'com.github.bumptech.glide:glide:4.12.0' + testImplementation 'junit:junit:4.+' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..e9283cf --- /dev/null +++ b/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.example.myapplication + +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.myapplication", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..e478b01 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/adapter/FollowerAdapter.kt b/app/src/main/java/com/example/myapplication/adapter/FollowerAdapter.kt new file mode 100644 index 0000000..a57937a --- /dev/null +++ b/app/src/main/java/com/example/myapplication/adapter/FollowerAdapter.kt @@ -0,0 +1,38 @@ +package com.example.myapplication.adapter + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.example.myapplication.data.FollowerData +import com.example.myapplication.databinding.ItemFollowerListBinding + + +class FollowerAdapter : RecyclerView.Adapter() { + val userList = mutableListOf() + + class FollowerViewHolder(private val binding : ItemFollowerListBinding) : RecyclerView.ViewHolder(binding.root){ + fun onBind(data: FollowerData) { + binding.tvName.text = data.name + binding.tvIntroduction.text = data.introduction + Glide.with(itemView.context) + .load(data.photo) + .apply(RequestOptions.circleCropTransform()) + .into(binding.ivProfile) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FollowerViewHolder { + val binding = ItemFollowerListBinding.inflate(LayoutInflater.from(parent.context),parent,false) + + return FollowerViewHolder(binding) + } + + override fun onBindViewHolder(holder: FollowerViewHolder, position: Int) { + holder.onBind(userList[position]) + } + + override fun getItemCount(): Int = userList.size + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/adapter/HomeTabViewPagerAdapter.kt b/app/src/main/java/com/example/myapplication/adapter/HomeTabViewPagerAdapter.kt new file mode 100644 index 0000000..60001dc --- /dev/null +++ b/app/src/main/java/com/example/myapplication/adapter/HomeTabViewPagerAdapter.kt @@ -0,0 +1,11 @@ +package com.example.myapplication.adapter + +import androidx.fragment.app.Fragment +import androidx.viewpager2.adapter.FragmentStateAdapter + +class HomeTabViewPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) { + val fragmentList = mutableListOf() + override fun getItemCount(): Int = fragmentList.size + + override fun createFragment(position: Int): Fragment = fragmentList[position] +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/adapter/RepositoryAdapter.kt b/app/src/main/java/com/example/myapplication/adapter/RepositoryAdapter.kt new file mode 100644 index 0000000..3221fd3 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/adapter/RepositoryAdapter.kt @@ -0,0 +1,30 @@ +package com.example.myapplication.adapter + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.example.myapplication.data.RepositoryData +import com.example.myapplication.databinding.ItemRepositoryListBinding + +class RepositoryAdapter : RecyclerView.Adapter() { + val repositoryList = mutableListOf() + + class RepositoryViewHolder(private val binding : ItemRepositoryListBinding) : RecyclerView.ViewHolder(binding.root){ + fun onBind(data: RepositoryData) { + binding.tvTitle.text = data.title + binding.tvContent.text = data.content + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RepositoryViewHolder { + val binding = ItemRepositoryListBinding.inflate(LayoutInflater.from(parent.context),parent,false) + + return RepositoryViewHolder(binding) + } + + override fun onBindViewHolder(holder: RepositoryViewHolder, position: Int) { + holder.onBind(repositoryList[position]) + } + + override fun getItemCount(): Int = repositoryList.size +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/adapter/SampleViewPagerAdapter.kt b/app/src/main/java/com/example/myapplication/adapter/SampleViewPagerAdapter.kt new file mode 100644 index 0000000..6b37666 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/adapter/SampleViewPagerAdapter.kt @@ -0,0 +1,13 @@ +package com.example.myapplication.adapter + +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter + +class SampleViewPagerAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) { + val fragments = mutableListOf() + + override fun getItemCount(): Int = fragments.size + + override fun createFragment(position: Int): Fragment = fragments[position] +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/api/SOPTSharedPreferences.kt b/app/src/main/java/com/example/myapplication/api/SOPTSharedPreferences.kt new file mode 100644 index 0000000..e0aba72 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/api/SOPTSharedPreferences.kt @@ -0,0 +1,20 @@ +package com.example.myapplication.api + +import android.content.Context + +object SOPTSharedPreferences { + private const val USER_AUTH = "USER_AUTH" + private const val AUTO_LOGIN = "AUTO_LOGIN" + + fun getAutoLogin(context: Context) : Boolean{ + val preferences = context.getSharedPreferences(USER_AUTH, Context.MODE_PRIVATE) + return preferences.getBoolean(AUTO_LOGIN, false) + } + + fun setAutoLogin(context: Context, auto : Boolean) { + val preferences = context.getSharedPreferences(USER_AUTH, Context.MODE_PRIVATE) + preferences.edit() + .putBoolean(AUTO_LOGIN,auto) + .apply() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/api/SampleService.kt b/app/src/main/java/com/example/myapplication/api/SampleService.kt new file mode 100644 index 0000000..6854cb6 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/api/SampleService.kt @@ -0,0 +1,26 @@ +package com.example.myapplication + +import com.example.myapplication.data.RequestLoginData +import com.example.myapplication.data.RequestSignUpData +import com.example.myapplication.data.ResponseLoginData +import com.example.myapplication.data.ResponseSignUpData +import retrofit2.Call +import retrofit2.http.Body +import retrofit2.http.Headers +import retrofit2.http.POST + +interface SampleService { + @Headers("Content-Type: application/json") + @POST("user/login") + fun postLogin( + @Body requestLoginData: RequestLoginData + ) : Call +} + +interface SignUpService { + @Headers("Content-Type: application/json") + @POST("user/signup") + fun postSignUp( + @Body requestSignUpData: RequestSignUpData + ) : Call +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/api/ServiceCreator.kt b/app/src/main/java/com/example/myapplication/api/ServiceCreator.kt new file mode 100644 index 0000000..6c12f7b --- /dev/null +++ b/app/src/main/java/com/example/myapplication/api/ServiceCreator.kt @@ -0,0 +1,29 @@ +package com.example.myapplication + +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +object ServiceCreator { + private const val BASE_URL = "https://asia-northeast3-we-sopt-29.cloudfunctions.net/api/" + + private val retrofit: Retrofit = Retrofit + .Builder() + .baseUrl(BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + val sampleService : SampleService = retrofit.create(SampleService::class.java) +} + + +object SignUpCreator { + private const val BASE_URL = "https://asia-northeast3-we-sopt-29.cloudfunctions.net/api/" + + private val retrofit: Retrofit = Retrofit + .Builder() + .baseUrl(BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + val signUpService : SignUpService = retrofit.create(SignUpService::class.java) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/data/FollowerData.kt b/app/src/main/java/com/example/myapplication/data/FollowerData.kt new file mode 100644 index 0000000..f47a8f5 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/data/FollowerData.kt @@ -0,0 +1,7 @@ +package com.example.myapplication.data + +data class FollowerData( + val name: String, + val introduction: String, + val photo : String +) diff --git a/app/src/main/java/com/example/myapplication/data/RepositoryData.kt b/app/src/main/java/com/example/myapplication/data/RepositoryData.kt new file mode 100644 index 0000000..2bfd06a --- /dev/null +++ b/app/src/main/java/com/example/myapplication/data/RepositoryData.kt @@ -0,0 +1,6 @@ +package com.example.myapplication.data + +data class RepositoryData( + val title: String, + val content: String +) diff --git a/app/src/main/java/com/example/myapplication/data/RequestLoginData.kt b/app/src/main/java/com/example/myapplication/data/RequestLoginData.kt new file mode 100644 index 0000000..609c186 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/data/RequestLoginData.kt @@ -0,0 +1,16 @@ +package com.example.myapplication.data + +import com.google.gson.annotations.SerializedName + +data class RequestLoginData( + @SerializedName("email") + val email: String, + val password: String +) + +data class RequestSignUpData( + @SerializedName("email") + val email: String, + val name: String, + val password: String +) \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/data/ResponseLoginData.kt b/app/src/main/java/com/example/myapplication/data/ResponseLoginData.kt new file mode 100644 index 0000000..05fba82 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/data/ResponseLoginData.kt @@ -0,0 +1,28 @@ +package com.example.myapplication.data + +data class ResponseLoginData( + val status: Int, + val success: Boolean, + val message: String, + val data: Data +) { + data class Data( + val id: Int, + val name: String, + val email: String + ) +} + + +data class ResponseSignUpData( + val status: Int, + val success: Boolean, + val message: String, + val data: Data +) { + data class Data( + val id: Int, + val name: String, + val email: String + ) +} diff --git a/app/src/main/java/com/example/myapplication/util/ViewExt.kt b/app/src/main/java/com/example/myapplication/util/ViewExt.kt new file mode 100644 index 0000000..79ddc8e --- /dev/null +++ b/app/src/main/java/com/example/myapplication/util/ViewExt.kt @@ -0,0 +1,8 @@ +package com.example.myapplication + +import android.content.Context +import android.widget.Toast + +fun Context.shortToast(message: String) { + Toast.makeText(this, message, Toast.LENGTH_SHORT).show() +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/view/camera/CameraFragment.kt b/app/src/main/java/com/example/myapplication/view/camera/CameraFragment.kt new file mode 100644 index 0000000..7e65982 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/camera/CameraFragment.kt @@ -0,0 +1,60 @@ +package com.example.myapplication.view.camera + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.myapplication.R + +// TODO: Rename parameter arguments, choose names that match +// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER +private const val ARG_PARAM1 = "param1" +private const val ARG_PARAM2 = "param2" + +/** + * A simple [Fragment] subclass. + * Use the [CameraFragment.newInstance] factory method to + * create an instance of this fragment. + */ +class CameraFragment : Fragment() { + // TODO: Rename and change types of parameters + private var param1: String? = null + private var param2: String? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + arguments?.let { + param1 = it.getString(ARG_PARAM1) + param2 = it.getString(ARG_PARAM2) + } + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_camera, container, false) + } + + companion object { + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @param param1 Parameter 1. + * @param param2 Parameter 2. + * @return A new instance of fragment CameraFragment. + */ + // TODO: Rename and change types and number of parameters + @JvmStatic + fun newInstance(param1: String, param2: String) = + CameraFragment().apply { + arguments = Bundle().apply { + putString(ARG_PARAM1, param1) + putString(ARG_PARAM2, param2) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/view/home/HomeActivity.kt b/app/src/main/java/com/example/myapplication/view/home/HomeActivity.kt new file mode 100644 index 0000000..8b96490 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/home/HomeActivity.kt @@ -0,0 +1,84 @@ +package com.example.myapplication.view.home + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import androidx.viewpager2.widget.ViewPager2 +import com.example.myapplication.R +import com.example.myapplication.adapter.SampleViewPagerAdapter +import com.example.myapplication.databinding.ActivityHomeBinding +import com.example.myapplication.view.camera.CameraFragment +import com.example.myapplication.view.profile.ProfileFragment + + +class HomeActivity : AppCompatActivity() { + //private var postion = FIRST_POSITION + private lateinit var SampleViewPagerAdapter: SampleViewPagerAdapter + private lateinit var binding : ActivityHomeBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityHomeBinding.inflate(layoutInflater) + + //initTransactionEvent() + initAdapter() + initBottomNavigation() + + setContentView(binding.root) + + } + +// fun initTransactionEvent() { +// val followerFragment = FollowerFragment() +// val repositstoryFragment = RepositoryFragment() +// +// supportFragmentManager.beginTransaction().add(R.id.container_rv, followerFragment).commit() +// +// binding.btnFollower.setOnClickListener { +// supportFragmentManager.beginTransaction().replace(R.id.container_rv, followerFragment) .commit() +// } +// +// binding.btnRepository.setOnClickListener { +// supportFragmentManager.beginTransaction().replace(R.id.container_rv, repositstoryFragment) .commit() +// } +// } + + private fun initAdapter() { + val fragmentList = listOf(ProfileFragment(), HomeFragment(), CameraFragment()) + + SampleViewPagerAdapter = SampleViewPagerAdapter(this) + SampleViewPagerAdapter.fragments.addAll(fragmentList) + + binding.vpSample.adapter = SampleViewPagerAdapter + } + + + private fun initBottomNavigation() { + binding.vpSample.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + binding.bottomNavigationView.menu.getItem(position).isChecked = true + } + }) + + binding.bottomNavigationView.setOnItemSelectedListener { + when(it.itemId) { + R.id.menu_profile -> { + binding.vpSample.currentItem = FIRST_FRAGMENT + } + R.id.menu_home -> { + binding.vpSample.currentItem = SECOND_FRAGMENT + } + else -> { + binding.vpSample.currentItem = THIRD_FRAGMENT + } + } + return@setOnItemSelectedListener true + } + } + + companion object { + const val FIRST_FRAGMENT = 0 + const val SECOND_FRAGMENT = 1 + const val THIRD_FRAGMENT = 2 + } +} + diff --git a/app/src/main/java/com/example/myapplication/view/home/HomeFollowerFragment.kt b/app/src/main/java/com/example/myapplication/view/home/HomeFollowerFragment.kt new file mode 100644 index 0000000..6fddc17 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/home/HomeFollowerFragment.kt @@ -0,0 +1,18 @@ +package com.example.myapplication.view.home + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.myapplication.R + +class home_follower_Fragment : Fragment() { + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_home_follower_, container, false) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/view/home/HomeFollowingFragment.kt b/app/src/main/java/com/example/myapplication/view/home/HomeFollowingFragment.kt new file mode 100644 index 0000000..a19d405 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/home/HomeFollowingFragment.kt @@ -0,0 +1,18 @@ +package com.example.myapplication.view.home + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.myapplication.R + +class home_following_Fragment : Fragment() { + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_home_following_, container, false) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/view/home/HomeFragment.kt b/app/src/main/java/com/example/myapplication/view/home/HomeFragment.kt new file mode 100644 index 0000000..c38e0ca --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/home/HomeFragment.kt @@ -0,0 +1,45 @@ +package com.example.myapplication.view.home + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.myapplication.databinding.FragmentHomeBinding +import com.google.android.material.tabs.TabLayoutMediator +import com.example.myapplication.adapter.HomeTabViewPagerAdapter + +class HomeFragment : Fragment() { + private lateinit var homeTabViewPagerAdapter: HomeTabViewPagerAdapter + private lateinit var binding: FragmentHomeBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentHomeBinding.inflate(layoutInflater) + + + initAdapter() + initTabLayout() + + return binding.root + } + + private fun initAdapter() { + val fragmentList = listOf(home_follower_Fragment(), home_following_Fragment()) + + homeTabViewPagerAdapter = HomeTabViewPagerAdapter(this) + homeTabViewPagerAdapter.fragmentList.addAll(fragmentList) + + binding.vpFollow.adapter = homeTabViewPagerAdapter + } + + private fun initTabLayout() { + val tabLabel = listOf("팔로잉", "팔로워") + + TabLayoutMediator(binding.tlFollow, binding.vpFollow) { tab, position -> + tab.text = tabLabel[position] + }.attach() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/view/login/SignInActivity.kt b/app/src/main/java/com/example/myapplication/view/login/SignInActivity.kt new file mode 100644 index 0000000..fd86ba6 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/login/SignInActivity.kt @@ -0,0 +1,82 @@ +package com.example.myapplication.view.login + +import android.content.Intent +import android.os.Bundle +import androidx.activity.result.ActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AppCompatActivity +import com.example.myapplication.api.SOPTSharedPreferences +import com.example.myapplication.databinding.ActivitySigninBinding +import com.example.myapplication.shortToast +import com.example.myapplication.view.home.HomeActivity + +class SignInActivity : AppCompatActivity() { + private lateinit var binding: ActivitySigninBinding + //private lateinit var getResultTextView: ActivityResultLauncher + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivitySigninBinding.inflate(layoutInflater) + + pressLogInBtnEvent() + pressSignUpBtnEvent() + + initClickEvent() + isAutoLogin() + + setContentView(binding.root) + } + + //로그인 버튼 눌렀을 때 이벤트 + private fun pressLogInBtnEvent() { + val intentHome = Intent(this, HomeActivity::class.java) + binding.apply { + btnLogin.setOnClickListener { + val userId = etId.text.toString() + val userPw = etPassword.text.toString() + + if (userId.isNotEmpty() && userPw.isNotEmpty()) { + startActivity(intentHome) + //Toast.makeText(this@SignInActivity, "$userId 님 환영합니다", Toast.LENGTH_SHORT).show() + shortToast("$userId 님 환영합니다") + } else { + shortToast("로그인 실패") + } + } + } + + } + + //회원가입 버튼 눌렀을 때 이벤트 + private fun pressSignUpBtnEvent() { + val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult -> } + binding.tvSignin.setOnClickListener { + startForResult.launch(Intent(this, SignUpActivity::class.java)) + } + + //id, pw 값 가지고 있을 경우 각 editText에 setText + if (intent.hasExtra("id") && intent.hasExtra("pw")) { + val id = intent.getStringExtra("id") + val pw = intent.getStringExtra("pw") + + binding.etId.setText(id) + binding.etPassword.setText(pw) + } + } + + private fun initClickEvent() { + binding.ivAutoLogin.setOnClickListener { + binding.ivAutoLogin.isSelected = !binding.ivAutoLogin.isSelected + + SOPTSharedPreferences.setAutoLogin(this, binding.ivAutoLogin.isSelected) + } + } + + private fun isAutoLogin() { + if(SOPTSharedPreferences.getAutoLogin(this)) { + shortToast("자동로그인 완료") + startActivity(Intent(this, HomeActivity::class.java)) + finish() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/view/login/SignUpActivity.kt b/app/src/main/java/com/example/myapplication/view/login/SignUpActivity.kt new file mode 100644 index 0000000..376fb40 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/login/SignUpActivity.kt @@ -0,0 +1,86 @@ +package com.example.myapplication.view.login + +import android.content.Intent +import android.os.Bundle +import android.util.Log +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import com.example.myapplication.data.RequestSignUpData +import com.example.myapplication.data.ResponseSignUpData +import com.example.myapplication.SignUpCreator +import com.example.myapplication.databinding.ActivitySignUpBinding +import com.example.myapplication.shortToast +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response + + +class SignUpActivity : AppCompatActivity() { + private lateinit var binding: ActivitySignUpBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivitySignUpBinding.inflate(layoutInflater) + setContentView(binding.root) + + pressSingUpBtnEvent() + } + + //회원가입 완료 버튼 눌렀을 때 이벤트 + fun pressSingUpBtnEvent() { + val intent = Intent(this, SignInActivity::class.java) + binding.apply { + btnSingup.setOnClickListener { + + initNetwork() + + val userName = etName.text.toString() + val userId = etId.text.toString() + val userPw = etPassword.text.toString() + + + if (userName.isNotEmpty() && userId.isNotEmpty() && userPw.trim().isNotEmpty()) { + intent + .putExtra("id", userId) + .putExtra("pw", userPw) + startActivity(intent) + finish() + + } else { + Toast.makeText(this@SignUpActivity, "입력되지 않은 정보가 있습니다", Toast.LENGTH_SHORT).show() + shortToast("입력되지 않은 정보가 있습니다.") + } + } + } + } + + private fun initNetwork() { + val requestSignUpData = RequestSignUpData( + binding.etName.text.toString(), + binding.etId.text.toString(), + binding.etPassword.text.toString() + ) + + val call : Call = SignUpCreator.signUpService.postSignUp(requestSignUpData) + call.enqueue(object : Callback { + override fun onResponse( + call: Call, + response: Response + ) { + if (response.isSuccessful) { + //Toast.makeText(this@SignUpActivity, response.body()?.message, Toast.LENGTH_SHORT).show() + response.body()?.message?.let { shortToast(it) } + } else { + Toast.makeText(this@SignUpActivity, "회원가입 실패", Toast.LENGTH_SHORT).show() + shortToast("회원가입 실패") + + } + } + + override fun onFailure(call: Call, t: Throwable) { + Log.e("NetworkTest", "error: $t") + } + }) + } +} + diff --git a/app/src/main/java/com/example/myapplication/view/onboarding/OnBoardingActivity.kt b/app/src/main/java/com/example/myapplication/view/onboarding/OnBoardingActivity.kt new file mode 100644 index 0000000..dd1f4fe --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/onboarding/OnBoardingActivity.kt @@ -0,0 +1,13 @@ +package com.example.myapplication.view.onboarding + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import com.example.myapplication.R + +class OnBoardingActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_on_boarding) + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/view/onboarding/OnboardingFragment1.kt b/app/src/main/java/com/example/myapplication/view/onboarding/OnboardingFragment1.kt new file mode 100644 index 0000000..89f030b --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/onboarding/OnboardingFragment1.kt @@ -0,0 +1,33 @@ +package com.example.myapplication.view.onboarding + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.navigation.fragment.findNavController +import com.example.myapplication.R +import com.example.myapplication.databinding.FragmentOnboarding1Binding + + + +class OnboardingFragment1 : Fragment() { + private lateinit var OnboardingFragment1: FragmentOnboarding1Binding + private var _binding: FragmentOnboarding1Binding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + _binding = FragmentOnboarding1Binding.inflate(layoutInflater, container, false) + initBtnEvent() + return binding.root + } + + fun initBtnEvent() { + binding.btnNext.setOnClickListener { + findNavController().navigate(R.id.action_onboardingFragment1_to_onboardingFragment2) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/view/onboarding/OnboardingFragment2.kt b/app/src/main/java/com/example/myapplication/view/onboarding/OnboardingFragment2.kt new file mode 100644 index 0000000..90f52f8 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/onboarding/OnboardingFragment2.kt @@ -0,0 +1,31 @@ +package com.example.myapplication.view.onboarding + +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.myapplication.R +import com.example.myapplication.databinding.FragmentOnboarding2Binding + +class OnboardingFragment2 : Fragment() { + private lateinit var OnboardingFragment2: FragmentOnboarding2Binding + private var _binding: FragmentOnboarding2Binding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + _binding = FragmentOnboarding2Binding.inflate(layoutInflater, container, false) + initBtnEvent() + return binding.root + } + + fun initBtnEvent() { + binding.btnNext.setOnClickListener { + findNavController().navigate(R.id.action_onboardingFragment2_to_onboardingFragment3) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/view/onboarding/OnboardingFragment3.kt b/app/src/main/java/com/example/myapplication/view/onboarding/OnboardingFragment3.kt new file mode 100644 index 0000000..e91767c --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/onboarding/OnboardingFragment3.kt @@ -0,0 +1,41 @@ +package com.example.myapplication.view.onboarding + +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.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.example.myapplication.R +import com.example.myapplication.databinding.FragmentOnboarding3Binding + +class OnboardingFragment3 : Fragment() { + private lateinit var OnboardingFragment3: FragmentOnboarding3Binding + private var _binding: FragmentOnboarding3Binding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + _binding = FragmentOnboarding3Binding.inflate(layoutInflater, container, false) + initBtnEvent() + + Glide.with(this) + .load("https://mblogthumb-phinf.pstatic.net/MjAxOTA0MjNfMjcy/MDAxNTU2MDIwNjg0ODMw.KwUiIDMhdpKzsuNX83GpdFljS1HjgNhCBNcXv2QXfxkg.ksHQVjDUTn8AMV4XVSfETLX-tZ1LTz9-bOmO0o7AtI8g.JPEG.ndh7782/%EC%B9%98%EC%A6%8801.JPG?type=w800") + .apply(RequestOptions.circleCropTransform()) + .into(binding.ivGit) + + return binding.root + } + + private fun initBtnEvent() { + binding.btnNext.setOnClickListener { + findNavController().navigate(R.id.action_onboardingFragment3_to_signInActivity) + + (activity as OnBoardingActivity).finish() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/view/profile/CancelAutoLoginActivity.kt b/app/src/main/java/com/example/myapplication/view/profile/CancelAutoLoginActivity.kt new file mode 100644 index 0000000..1346eb0 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/profile/CancelAutoLoginActivity.kt @@ -0,0 +1,30 @@ +package com.example.myapplication.view.profile + +import android.content.SharedPreferences +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import com.example.myapplication.databinding.ActivityCancelAutoLoginBinding + + +class CancelAutoLoginActivity : AppCompatActivity() { + private lateinit var binding: ActivityCancelAutoLoginBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityCancelAutoLoginBinding.inflate(layoutInflater) + + initClickEvent() + + setContentView(binding.root) + } + + private fun initClickEvent() { + binding.tvOffAutoLogin.setOnClickListener { + val settings: SharedPreferences = getSharedPreferences("USER_AUTH", MODE_PRIVATE) + val editor: SharedPreferences.Editor = settings.edit() + editor.remove("int") + editor.clear() + editor.commit() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/view/profile/FollowerFragment.kt b/app/src/main/java/com/example/myapplication/view/profile/FollowerFragment.kt new file mode 100644 index 0000000..298c626 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/profile/FollowerFragment.kt @@ -0,0 +1,45 @@ +package com.example.myapplication.view.profile + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.example.myapplication.adapter.FollowerAdapter +import com.example.myapplication.data.FollowerData +import com.example.myapplication.databinding.FollowerFragmentBinding + + +class FollowerFragment : Fragment() { + private lateinit var follwerAdapter: FollowerAdapter + private var _binding: FollowerFragmentBinding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + _binding = FollowerFragmentBinding.inflate(layoutInflater, container,false) + + + follwerAdapter = FollowerAdapter() + binding.rvFollower.adapter = follwerAdapter + + follwerAdapter.userList.addAll( + listOf( + FollowerData("스폰지밥", "안녕하세요", "https://ww.namu.la/s/bd52223e4d1f11fcc4c7f6506bf3321b26579bf118db6c1ca20492b9af4228a414edd25f1006baace220e4ca771288e0f38d6cbf253ae4e9d39aaf4b881600b0d65e518e7d94891837ee9a0c6a723aac0f4d2b7bf4a65b36bd1fe636aa49c632"), + FollowerData("뚱이", "안녕하세요", "https://img.insight.co.kr/static/2020/08/12/700/fyzvinle3b068ce501hq.jpg"), + FollowerData("집게사장", "안녕하세요", "https://pbs.twimg.com/media/D8RITHlV4AAb1iG.jpg") + ) + ) + follwerAdapter.notifyDataSetChanged() + return binding.root + } + + override fun onDestroy() { + super.onDestroy() + _binding = null + } + +} + diff --git a/app/src/main/java/com/example/myapplication/view/profile/ProfileFragment.kt b/app/src/main/java/com/example/myapplication/view/profile/ProfileFragment.kt new file mode 100644 index 0000000..fea9cef --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/profile/ProfileFragment.kt @@ -0,0 +1,70 @@ +package com.example.myapplication.view.profile + +import android.content.Intent +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.example.myapplication.R +import com.example.myapplication.databinding.FragmentProfileBinding + + +class ProfileFragment : Fragment() { + private lateinit var ProfileFragment: FragmentProfileBinding + private var _binding: FragmentProfileBinding? = null + private val binding get() = _binding!! + + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + _binding = FragmentProfileBinding.inflate(layoutInflater, container, false) + + initSettingListener() + initTransactionEvent() + + Glide.with(this) + .load("https://mblogthumb-phinf.pstatic.net/MjAxOTA0MjNfMjcy/MDAxNTU2MDIwNjg0ODMw.KwUiIDMhdpKzsuNX83GpdFljS1HjgNhCBNcXv2QXfxkg.ksHQVjDUTn8AMV4XVSfETLX-tZ1LTz9-bOmO0o7AtI8g.JPEG.ndh7782/%EC%B9%98%EC%A6%8801.JPG?type=w800") + .apply(RequestOptions.circleCropTransform()) + .into(binding.ivProfile) + + binding.btnFollower.isSelected = true; + + return binding.root + } + + fun initTransactionEvent() { + val followerFragment = FollowerFragment() + val repositstoryFragment = RepositoryFragment() + + getActivity()?.getSupportFragmentManager() + + getActivity()?.supportFragmentManager?.beginTransaction() + ?.add(R.id.container_rv, followerFragment)?.commit() + + binding.btnFollower.setOnClickListener { + getActivity()?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.container_rv, followerFragment)?.commit() + binding.btnFollower.isSelected = true; + binding.btnRepository.isSelected = false; + } + + binding.btnRepository.setOnClickListener { + getActivity()?.supportFragmentManager?.beginTransaction() + ?.replace(R.id.container_rv, repositstoryFragment)?.commit() + binding.btnRepository.isSelected = true; + binding.btnFollower.isSelected = false; + } + } + + private fun initSettingListener() { + binding.ivSetting.setOnClickListener { + val intent = Intent(this@ProfileFragment.context, CancelAutoLoginActivity::class.java) + startActivity(intent) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/view/profile/RepositoryFragment.kt b/app/src/main/java/com/example/myapplication/view/profile/RepositoryFragment.kt new file mode 100644 index 0000000..d3753d4 --- /dev/null +++ b/app/src/main/java/com/example/myapplication/view/profile/RepositoryFragment.kt @@ -0,0 +1,44 @@ +package com.example.myapplication.view.profile + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.example.myapplication.adapter.RepositoryAdapter +import com.example.myapplication.data.RepositoryData +import com.example.myapplication.databinding.RepositoryFragmentBinding + +class RepositoryFragment : Fragment() { + private lateinit var repositoryAdapter: RepositoryAdapter + private var _binding: RepositoryFragmentBinding? = null + private val binding get() = _binding!! + + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + _binding = RepositoryFragmentBinding.inflate(layoutInflater, container,false) + + repositoryAdapter = RepositoryAdapter() + binding.rvRepository.adapter = repositoryAdapter + + repositoryAdapter.repositoryList.addAll( + listOf( + RepositoryData("안드로이드레파지토리", "안녕하세요안녕하세요안녕하세요"), + RepositoryData("안드로이드레파지토리1", "안녕하세요"), + RepositoryData("안드로이드레파지토리2", "안녕하세요"), + RepositoryData("안드로이드레파지토리3", "안녕하세요") + ) + ) + repositoryAdapter.notifyDataSetChanged() + + return binding.root + } + + override fun onDestroy() { + super.onDestroy() + _binding = null + } +} diff --git a/app/src/main/res/color/selector_text_color.xml b/app/src/main/res/color/selector_text_color.xml new file mode 100644 index 0000000..309157d --- /dev/null +++ b/app/src/main/res/color/selector_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/android_logo.png b/app/src/main/res/drawable-v24/android_logo.png new file mode 100644 index 0000000..fa3d262 Binary files /dev/null and b/app/src/main/res/drawable-v24/android_logo.png differ diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/img_github.png b/app/src/main/res/drawable-v24/img_github.png new file mode 100644 index 0000000..6fc89b1 Binary files /dev/null and b/app/src/main/res/drawable-v24/img_github.png differ diff --git a/app/src/main/res/drawable/btn_fill_gray.xml b/app/src/main/res/drawable/btn_fill_gray.xml new file mode 100644 index 0000000..b3efe57 --- /dev/null +++ b/app/src/main/res/drawable/btn_fill_gray.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/btn_fill_orange.xml b/app/src/main/res/drawable/btn_fill_orange.xml new file mode 100644 index 0000000..33d20e5 --- /dev/null +++ b/app/src/main/res/drawable/btn_fill_orange.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/btn_fill_pink.xml b/app/src/main/res/drawable/btn_fill_pink.xml new file mode 100644 index 0000000..f581d98 --- /dev/null +++ b/app/src/main/res/drawable/btn_fill_pink.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/app/src/main/res/drawable/btn_fill_white.xml b/app/src/main/res/drawable/btn_fill_white.xml new file mode 100644 index 0000000..e52533b --- /dev/null +++ b/app/src/main/res/drawable/btn_fill_white.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/et_border_pink.xml b/app/src/main/res/drawable/et_border_pink.xml new file mode 100644 index 0000000..624202d --- /dev/null +++ b/app/src/main/res/drawable/et_border_pink.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/et_fill_gray.xml b/app/src/main/res/drawable/et_fill_gray.xml new file mode 100644 index 0000000..0de0bd2 --- /dev/null +++ b/app/src/main/res/drawable/et_fill_gray.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_camera_gray.xml b/app/src/main/res/drawable/ic_camera_gray.xml new file mode 100644 index 0000000..47303d8 --- /dev/null +++ b/app/src/main/res/drawable/ic_camera_gray.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_camera_pink.xml b/app/src/main/res/drawable/ic_camera_pink.xml new file mode 100644 index 0000000..a3c9e85 --- /dev/null +++ b/app/src/main/res/drawable/ic_camera_pink.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_checkbox_off.xml b/app/src/main/res/drawable/ic_checkbox_off.xml new file mode 100644 index 0000000..333fac0 --- /dev/null +++ b/app/src/main/res/drawable/ic_checkbox_off.xml @@ -0,0 +1,15 @@ + + + + diff --git a/app/src/main/res/drawable/ic_checkbox_on.xml b/app/src/main/res/drawable/ic_checkbox_on.xml new file mode 100644 index 0000000..dd69d0f --- /dev/null +++ b/app/src/main/res/drawable/ic_checkbox_on.xml @@ -0,0 +1,15 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home_gray.xml b/app/src/main/res/drawable/ic_home_gray.xml new file mode 100644 index 0000000..fd99695 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_gray.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_home_pink.xml b/app/src/main/res/drawable/ic_home_pink.xml new file mode 100644 index 0000000..e0add2b --- /dev/null +++ b/app/src/main/res/drawable/ic_home_pink.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_img_github.xml b/app/src/main/res/drawable/ic_img_github.xml new file mode 100644 index 0000000..94716c1 --- /dev/null +++ b/app/src/main/res/drawable/ic_img_github.xml @@ -0,0 +1,8 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_person_gray.xml b/app/src/main/res/drawable/ic_person_gray.xml new file mode 100644 index 0000000..fb785ee --- /dev/null +++ b/app/src/main/res/drawable/ic_person_gray.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_person_pink.xml b/app/src/main/res/drawable/ic_person_pink.xml new file mode 100644 index 0000000..d372549 --- /dev/null +++ b/app/src/main/res/drawable/ic_person_pink.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/img_setting_white.png b/app/src/main/res/drawable/img_setting_white.png new file mode 100644 index 0000000..2276f6a Binary files /dev/null and b/app/src/main/res/drawable/img_setting_white.png differ diff --git a/app/src/main/res/drawable/line_pink.xml b/app/src/main/res/drawable/line_pink.xml new file mode 100644 index 0000000..381b0dd --- /dev/null +++ b/app/src/main/res/drawable/line_pink.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_btn_orange.xml b/app/src/main/res/drawable/selector_btn_orange.xml new file mode 100644 index 0000000..c9ddf5d --- /dev/null +++ b/app/src/main/res/drawable/selector_btn_orange.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_checkbox.xml b/app/src/main/res/drawable/selector_checkbox.xml new file mode 100644 index 0000000..a7ca801 --- /dev/null +++ b/app/src/main/res/drawable/selector_checkbox.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_icon.xml b/app/src/main/res/drawable/selector_icon.xml new file mode 100644 index 0000000..b2d04a3 --- /dev/null +++ b/app/src/main/res/drawable/selector_icon.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_tf_gray.xml b/app/src/main/res/drawable/selector_tf_gray.xml new file mode 100644 index 0000000..e6dae88 --- /dev/null +++ b/app/src/main/res/drawable/selector_tf_gray.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/font/noto_sans_kr.xml b/app/src/main/res/font/noto_sans_kr.xml new file mode 100644 index 0000000..2ba8dda --- /dev/null +++ b/app/src/main/res/font/noto_sans_kr.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/font/noto_sans_kr_black.otf b/app/src/main/res/font/noto_sans_kr_black.otf new file mode 100644 index 0000000..0cfa4bb Binary files /dev/null and b/app/src/main/res/font/noto_sans_kr_black.otf differ diff --git a/app/src/main/res/font/noto_sans_kr_bold.otf b/app/src/main/res/font/noto_sans_kr_bold.otf new file mode 100644 index 0000000..7f4131c Binary files /dev/null and b/app/src/main/res/font/noto_sans_kr_bold.otf differ diff --git a/app/src/main/res/font/noto_sans_kr_light.otf b/app/src/main/res/font/noto_sans_kr_light.otf new file mode 100644 index 0000000..03f948c Binary files /dev/null and b/app/src/main/res/font/noto_sans_kr_light.otf differ diff --git a/app/src/main/res/font/noto_sans_kr_medium.otf b/app/src/main/res/font/noto_sans_kr_medium.otf new file mode 100644 index 0000000..d8cacce Binary files /dev/null and b/app/src/main/res/font/noto_sans_kr_medium.otf differ diff --git a/app/src/main/res/font/noto_sans_kr_regular.otf b/app/src/main/res/font/noto_sans_kr_regular.otf new file mode 100644 index 0000000..e26c1cd Binary files /dev/null and b/app/src/main/res/font/noto_sans_kr_regular.otf differ diff --git a/app/src/main/res/font/noto_sans_kr_thin.otf b/app/src/main/res/font/noto_sans_kr_thin.otf new file mode 100644 index 0000000..6bc00c4 Binary files /dev/null and b/app/src/main/res/font/noto_sans_kr_thin.otf differ diff --git a/app/src/main/res/layout/activity_cancel_auto_login.xml b/app/src/main/res/layout/activity_cancel_auto_login.xml new file mode 100644 index 0000000..2a68248 --- /dev/null +++ b/app/src/main/res/layout/activity_cancel_auto_login.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml new file mode 100644 index 0000000..28571fc --- /dev/null +++ b/app/src/main/res/layout/activity_home.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_on_boarding.xml b/app/src/main/res/layout/activity_on_boarding.xml new file mode 100644 index 0000000..542c9c5 --- /dev/null +++ b/app/src/main/res/layout/activity_on_boarding.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_sign_up.xml b/app/src/main/res/layout/activity_sign_up.xml new file mode 100644 index 0000000..70a764d --- /dev/null +++ b/app/src/main/res/layout/activity_sign_up.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + +