무료
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결하울의 안드로이드 인스타그램 클론 만들기
파이어베이스랑 연동이 너무 느립니다
약 5분간은 기다려야 화면이 뜨네요.. 해결방법이 있을요?
- 미해결하울의 안드로이드 인스타그램 클론 만들기
8강 상세페이지 화면 만들기를 하고 나서 로그인시 다음과 같은 오류가 뜹니다.
I/ViewRootImpl@bb89e77[LoginActivity]: stopped(true) old=false W/Glide: Load failed for https://firebasestorage.googleapis.com/v0/b/howlstagram-f16-b04b9.appspot.com/o/image%2FIMAGE_20210222_181559_.png?alt=media&token=116f917c-1594-4e4b-bb8a-8973ba56e45b with size [92x92] class com.bumptech.glide.load.engine.GlideException: Failed to load resource해당 링크를 들어가면 이런 창이 열립니다.{ "error": { "code": 403, "message": "Permission denied. Could not perform this operation" } }이렇게 뜨구요.firebase 규칙에 적었던 부분은service cloud.firestore { match /databases/{database}/documents{ match /{document=**} { allow read,write: if request.auth.uid !=null; } } }왜 권한이 없는지 알 수 있을까요?
- 미해결하울의 안드로이드 인스타그램 클론 만들기
LoginActivity.kt 파일 내용이 달라요
기존 내용 삭제하고 진행하면 되나요? 추가로 해당 소스 있는 VCS 주소 좀 같이 주세요 package com.example.ostagram_f16.ui.loginimport android.app.Activityimport androidx.lifecycle.Observerimport androidx.lifecycle.ViewModelProviderimport android.os.Bundleimport androidx.annotation.StringResimport androidx.appcompat.app.AppCompatActivityimport android.text.Editableimport android.text.TextWatcherimport android.view.Viewimport android.view.inputmethod.EditorInfoimport android.widget.Buttonimport android.widget.EditTextimport android.widget.ProgressBarimport android.widget.Toastimport com.example.ostagram_f16.Rclass LoginActivity : AppCompatActivity() { private lateinit var loginViewModel: LoginViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_login) val username = findViewById<EditText>(R.id.username) val password = findViewById<EditText>(R.id.password) val login = findViewById<Button>(R.id.login) val loading = findViewById<ProgressBar>(R.id.loading) loginViewModel = ViewModelProvider(this, LoginViewModelFactory()) .get(LoginViewModel::class.java) loginViewModel.loginFormState.observe(this@LoginActivity, Observer { val loginState = it ?: return@Observer // disable login button unless both username / password is valid login.isEnabled = loginState.isDataValid if (loginState.usernameError != null) { username.error = getString(loginState.usernameError) } if (loginState.passwordError != null) { password.error = getString(loginState.passwordError) } }) loginViewModel.loginResult.observe(this@LoginActivity, Observer { val loginResult = it ?: return@Observer loading.visibility = View.GONE if (loginResult.error != null) { showLoginFailed(loginResult.error) } if (loginResult.success != null) { updateUiWithUser(loginResult.success) } setResult(Activity.RESULT_OK) //Complete and destroy login activity once successful finish() }) username.afterTextChanged { loginViewModel.loginDataChanged( username.text.toString(), password.text.toString() ) } password.apply { afterTextChanged { loginViewModel.loginDataChanged( username.text.toString(), password.text.toString() ) } setOnEditorActionListener { _, actionId, _ -> when (actionId) { EditorInfo.IME_ACTION_DONE -> loginViewModel.login( username.text.toString(), password.text.toString() ) } false } login.setOnClickListener { loading.visibility = View.VISIBLE loginViewModel.login(username.text.toString(), password.text.toString()) } } } private fun updateUiWithUser(model: LoggedInUserView) { val welcome = getString(R.string.welcome) val displayName = model.displayName // TODO : initiate successful logged in experience Toast.makeText( applicationContext, "$welcome $displayName", Toast.LENGTH_LONG ).show() } private fun showLoginFailed(@StringRes errorString: Int) { Toast.makeText(applicationContext, errorString, Toast.LENGTH_SHORT).show() }}/** * Extension function to simplify setting an afterTextChanged action to EditText components. */fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) { this.addTextChangedListener(object : TextWatcher { override fun afterTextChanged(editable: Editable?) { afterTextChanged.invoke(editable.toString()) } override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {} })}
- 미해결하울의 안드로이드 인스타그램 클론 만들기
상세화면 페이지 만들기 강의중
DetailViewFragment 코틀린파일안에 onCreateView 메소드 에서 구현하는 view.findViewById<RecyclerView>(R.id.detailviewfragment_recyclerview).adapter = DetailViewRecyclerViewAdapter()view.findViewById<RecyclerView>(R.id.detailviewfragment_recyclerview).layoutManager = LinearLayoutManager(activity) 이 부분중 findViewById부분이 노란색으로 표시되면서 The id R.id.detailviewfragment_recyclerview has already been looked up in this method; possible cut & paste error? (First usage here) 이런 메시지가 뜹니다. 그러면서 아래와같이 코드를 오류없이 따라 쳤는데 게시글부분이 나오질 않습니다. 앱을 실행해도 에러없이 켜지고 동작은하는데 게시글이 나오지 않습니다. Firebase store 부분에도 폴더가 만들어져있고 업로드한 파일이 잘 들어가 있습니다. class DetailViewFragment : Fragment() { var firestore: FirebaseFirestore? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val view = LayoutInflater.from(activity).inflate(R.layout.fragment_detail, container, false) firestore = FirebaseFirestore.getInstance() view.findViewById<RecyclerView>(R.id.detailviewfragment_recyclerview).adapter = DetailViewRecyclerViewAdapter() view.findViewById<RecyclerView>(R.id.detailviewfragment_recyclerview).layoutManager = LinearLayoutManager(activity) return view } inner class DetailViewRecyclerViewAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() { var contentDTOs: ArrayList<ContentDTO> = arrayListOf() var contentUidList: ArrayList<String> = arrayListOf() init { firestore?.collection("image")?.orderBy("timestamp") ?.addSnapshotListener { querySnapshot, firebaseFirestoreException -> contentDTOs.clear() contentUidList.clear() for (snapshot in querySnapshot!!.documents) { val item = snapshot.toObject(ContentDTO::class.java) contentDTOs.add(item!!) contentUidList.add(snapshot.id) } notifyDataSetChanged() } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_detail, parent, false) return CustomViewHolder(view) } inner class CustomViewHolder(view: View) : RecyclerView.ViewHolder(view) override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { val viewholder = (holder as CustomViewHolder).itemView //User id viewholder.findViewById<TextView>(R.id.detailviewitem_profile_textview).text = contentDTOs[position].userId //Image Glide.with(holder.itemView.context).load(contentDTOs[position].imageUrl).into(viewholder.findViewById(R.id.detailviewitem_imageview_content)) //Explain of content viewholder.findViewById<TextView>(R.id.detailviewitem_explain_textview).text = contentDTOs[position].explain //likes viewholder.findViewById<TextView>(R.id.detailviewitem_favoritecounter_textview).text = "Likes" + contentDTOs!![position].favoriteCount //Profile Image Glide.with(holder.itemView.context).load(contentDTOs[position].imageUrl).into(viewholder.findViewById(R.id.detailviewitem_profile_image)) } override fun getItemCount(): Int { return contentDTOs.size } }}
- 미해결하울의 안드로이드 인스타그램 클론 만들기
좋아요 버튼을 java adapter 에서 처리하고싶습니다
좋아요 버튼을 java adapter 에서 하려면 어떻게 해야됩니까???? 예제 자바코드는 파이어 리얼타임 베이스라서 잘모르겠습니다 이다음을 어떻게 해야할지 잘 모르겠습니다 @Overridepublic void onClick(View v) { if(v.getId() == R.id.detailviewitem_favorite_imageview) { DocumentReference tsdoc = FirebaseFirestore.getInstance().collection("images").document(contentUidList.get(position)); }}
- 미해결하울의 안드로이드 인스타그램 클론 만들기
emulator에서 createUserwithEmailAndPassword
emulator에서 createUserwithEmailAndPassword가 실행되지 않아서 질문드립니다. 로그를 찍어서 signinAndSignup 메소드에는 도착했지만 moveMainPage가 실행되지 않았습니다. 그래서 else if , else 구문에서도 모두 로그를 찍어보고 addOnFailureListener에서도 로그찍어서 확인해봤지만 어느쪽에도 들어가지 않았습니다. 구글링을 통해서 알아본 결과 애뮬레이터 오류이고 실제 디바이스로 할 경우 잘 되었습니다. Local module descriptor class for com.google.firebase.auth not found 이런 오류로 인해 되지 않았던 것 같습니다. 혹시 강사님께서는 에뮬레이터의 os 버전과 기기 종류는 어떤걸로 실습하였는지 질문드립니다.
- 미해결하울의 안드로이드 인스타그램 클론 만들기
DetailViewFramgment 구현 중 viewholder를 사용 시 item.detail이 불러와 지지 않습니다.
초보라서 정확한 상황을 설명할 순 없지만 이번 장 구현할 때 똑같이 구현했는데도 전 item.detail의 id들이 불러와지질 않습니다. import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.appcompat.view.menu.MenuView import androidx.fragment.app.Fragment import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.example.instagram.R import com.example.instagram.navigation.model.ContentDTO import com.google.firebase.firestore.FirebaseFirestore class DetailViewFragment : Fragment() { var firestore: FirebaseFirestore? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { var view = LayoutInflater.from(activity).inflate(R.layout.fragment_detail, container, false) firestore = FirebaseFirestore.getInstance() return view } inner class DetailViewRecyclerViewAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() { var contentDTOs: ArrayList<ContentDTO> = arrayListOf() var contentUidList: ArrayList<String> = arrayListOf() init { firestore?.collection("images")?.orderBy("timestamp") ?.addSnapshotListener { querySnapshot, firebaseFirestoreException -> contentDTOs.clear() contentUidList.clear() for (snapshot in querySnapshot!!.documents) { var item = snapshot.toObject(ContentDTO::class.java) contentDTOs.add(item!!) contentUidList.add(snapshot.id) } notifyDataSetChanged() } } override fun onCreateViewHolder(p0: ViewGroup, p1: Int): RecyclerView.ViewHolder { var view = LayoutInflater.from(p0.context).inflate(R.layout.item_detail, p0, false) return CustomViewHolder(view) } inner class CustomViewHolder(view: View) : RecyclerView.ViewHolder(view) override fun getItemCount(): Int { return contentDTOs.size } override fun onBindViewHolder(p0: RecyclerView.ViewHolder, p1: Int) { var viewholder = (p0 as CustomViewHolder).itemView //Userid viewholder.detale Glide.with(p0.itemView.context).load(contentDTOs!![p1].imageUri).into(viewholder.deta) } } }
- 미해결하울의 안드로이드 인스타그램 클론 만들기
signinAndSignup 과 signEmail 을 분리하는 이유가 뭔가요?
둘이 어떤 다른 기능을 하는 건가요? 코드가 거의 똑같아서 왜 두개를 만든 건지 이해가 안돼요. 전체적으로 이런 상황일 땐 이렇게 흘러가고, 저런 상황일 땐 저렇게 흘러가서 무엇이 실행되는건지 설명 조금만 더 부탁드립니다.
- 미해결하울의 안드로이드 인스타그램 클론 만들기
안드로이드 스튜디오 4.1.1 (맥 m1 ) 사용 해서 강의 듣고 있는데 자꾸 gradle.build에서 라이브러리 추가 할때 에러가 납니다ㅠㅠ
제목과 같이 해당 프로그램과 노트북을 사용하고 있습니다 m1은 에뮬레이터가 안돼서 usb로 안드로이드 기기 연결하여 결과창 보고있습니다! 강의에서 알려주시는 Gradle.build 의 버전이 달라서 그런지, 자꾸 에러가 납니다... 구글이나 페이스북으로 로그인하려고 하면 튕겨서 갑자기 종료되고, 로그인 버튼을 누르자마자 Logcat에서는 다음 사진과 같이 can not find class라는 문장이 수두룩 합니다ㅠㅠ 다음 동영상 진도를 나가고자 매일 이메일 회원가입으로 들어가서 사진업로드와 컨텐츠를업로드 하려고 해도 똑같은 현상이 발생하여 진도가 도저히 안나가서 이렇게 질문드립니다..ㅠㅠ 코틀린을 강의로 배우고 있기 때문에 혹시 제 프로그램에 맞는 여러가지 라이브러리 버전을 알맞게 맞추는 방법이나 다른 방법으로 해결해주실 수 있는지 질문 드립니다ㅜㅠㅠㅠㅠ (해당 빨간 문장은 한 7줄 정도 나옵니다)
- 미해결하울의 안드로이드 인스타그램 클론 만들기
Single Dex 문제 해결방법
defaultConfig { applicationId "com.datacompany.instagram" minSdkVersion 19 targetSdkVersion 30 versionCode 1 versionName "1.0" //Dex 에러땜에 추가 multiDexEnabled true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"} 모듈수준의 그래들에 위아래 것들 추가하시면 됩니다. //Dex 에러땜에 추가implementation 'androidx.multidex:multidex:2.0.1'
- 미해결하울의 안드로이드 인스타그램 클론 만들기
파이어베이스 -> Database가 아닌 Cloud Firebase입니다.
파이어베이스 -> Database가 아닌 Cloud Firebase입니다. 업데이트 되어 영상과 좀 다릅니다. rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.auth.uid != null; } } }
- 미해결하울의 안드로이드 인스타그램 클론 만들기
사진 업로드 버튼 누를때 오류나거나, 로그인페이지로 가거나, 앱종료되시는 분들
<activity android:name=".navigation.AddPhotoActivity"></activity> manifest에 추가되어있나 확인해보세용
- 미해결하울의 안드로이드 인스타그램 클론 만들기
[개선코드]비밀번호 6자리일 땐 오류 납니다. 다음 코드 확인해주세요.
// 회원가입 or 로그인하는 코드fun signinAndSignup(){ auth?.createUserWithEmailAndPassword(email_edittext.text.toString(), password_edittext.text.toString()) ?.addOnCompleteListener{ task -> if(task.isSuccessful){ println("_________________________________________task succesful") // creating a user account moveMainPage(task.result?.user) } else if(task.exception?.message.isNullOrEmpty()){ println("_________________________________________FUCKING ERROR") //show the error message Toast.makeText(this, task.exception?.message, Toast.LENGTH_LONG).show() } else { println("_________________________________________FUCKGING SIGNIN EMAIL") if(password_edittext.text.toString().length < 6){ println("_________________________________________FUCKGING SIGNIN EMAIL_PASSWORD LENGTH PROBLEM") println("_______________________________________${password_edittext.text.toString().length}") Toast.makeText(this, "패스워드는 최소 6자리 이상이여야 합니다. 다시 입력 바랍니다.", Toast.LENGTH_LONG).show() }else{ println("_________________________________________FUCKGING SIGNIN EMAIL_SIGNINEMAIL") println("_______________________________________${password_edittext.text.toString().length}") // login if you have account signinEmail() } } }} 프린트문은 지우고 하셔두 됩니다. // 회원가입 or 로그인하는 코드fun signinAndSignup(){ auth?.createUserWithEmailAndPassword(email_edittext.text.toString(), password_edittext.text.toString()) ?.addOnCompleteListener{ task -> if(task.isSuccessful){ // creating a user account moveMainPage(task.result?.user) } else if(task.exception?.message.isNullOrEmpty()){ //show the error message Toast.makeText(this, task.exception?.message, Toast.LENGTH_LONG).show() } else { // 비밀번호가 6자리 미만일 때 Toast 띄우기! if(password_edittext.text.toString().length < 6){ Toast.makeText(this, "패스워드는 최소 6자리 이상이여야 합니다. 다시 입력 바랍니다.", Toast.LENGTH_LONG).show() }else{ // 비밀번호가 6자리 이상일 때, 회원가입하고 로그인하기 signinEmail() } } }}
- 미해결하울의 안드로이드 인스타그램 클론 만들기
9분 30초경 onCreate 오류나면 확인하세요.
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE), 1) android.Manifest 입니다,
- 미해결하울의 안드로이드 인스타그램 클론 만들기
android.support.design은 사용안됩니다. 아래꺼 사용하세요
<com.google.android.material.textfield.TextInputLayout android:id="@+id/editText" android:layout_below="@id/toorbar_division" android:layout_toRightOf="@+id/addphoto_image" android:layout_height="match_parent" android:layout_width="match_parent"></com.google.android.material.textfield.TextInputLayout>
- 미해결하울의 안드로이드 인스타그램 클론 만들기
android.support.constraint.ConstraintLayout 없으신분들 https://developer.android.com/training/constraint-layout?hl=ko
android.support.constraint.ConstraintLayout 없으신분들https://developer.android.com/training/constraint-layout?hl=ko
- 미해결하울의 안드로이드 인스타그램 클론 만들기
<RelativeLayout
activity_login.xml에서 <RelativeLayout으로 바꾸는거에서부터 막히네요....이렇게 바꾸면 오류라고 빨간글씨로 바뀝니다
- 미해결하울의 안드로이드 인스타그램 클론 만들기
상세화면 챕터 후 로그인 시 튕깁니다. 누구든 부탁드립니다. 도와주세요.
storage에 업로드하는 강의까지 아무 오류없이 로그인도 잘되고 잘됐습니다. 근데 이번 강의를 모두 작성한 후 로그인시 화면이 튕깁니다. 코드에 오류는 전혀 없고 3일동안 프로젝트랑 파이어베이스랑 전부 다 5번 지우고 다시 똑같이 따라써서 한글자도 하나의 설정도 틀린 것이 없습니다. 또한 하울님의 github 코드를 복붙해도 완전히 똑같은 오류가 납니다. Migrate to AndroidX , clean, rebuild, restart 백번했습니다. MainActivity.kt에 Oncreate에서 상세화면 페이지를 부르는 이 코드를 지우면 로그인을 해도 화면이 튕기지 않습니다. bottom_navigation.selectedItemId = R.id.action_home Run 창에 E/AndroidRuntime: FATAL EXCEPTION: grpc-default-executor-0 Process: com.example.jbstagram_try1, PID: 30258 java.lang.AssertionError at io.grpc.internal.DnsNameResolver.getResourceResolver(DnsNameResolver.java:536) at io.grpc.internal.DnsNameResolver.access$500(DnsNameResolver.java:60) at io.grpc.internal.DnsNameResolver$1.run(DnsNameResolver.java:211) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:764) 이 오류가 뜨면서 로그인시 메인화면이 뜨자마자 튕기며 제 DetailViewFragment.kt의 코드는 이렇습니다. package com.example.jbstagram_try1.navigationimport android.os.Bundleimport android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupimport androidx.fragment.app.Fragmentimport androidx.recyclerview.widget.LinearLayoutManagerimport androidx.recyclerview.widget.RecyclerViewimport com.bumptech.glide.Glideimport com.example.jbstagram_try1.Rimport com.example.jbstagram_try1.navigation.model.ContentDTOimport com.google.firebase.firestore.FirebaseFirestoreimport kotlinx.android.synthetic.main.item_detail.view.*import kotlinx.android.synthetic.main.fragment_detail.view.*//class DetailViewFragment : Fragment(){ var firestore : FirebaseFirestore? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { var view = LayoutInflater.from(activity).inflate(R.layout.fragment_detail,container,false) firestore = FirebaseFirestore.getInstance() view.detailviewfragment_recyclerview.adapter = DetailViewRecyclerViewAdapter() view.detailviewfragment_recyclerview.layoutManager = LinearLayoutManager(activity) return view } inner class DetailViewRecyclerViewAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>(){ var contentDTOs : ArrayList<ContentDTO> = arrayListOf() var contentUidList : ArrayList<String> = arrayListOf() init { firestore?.collection("images")?.orderBy("timestamp")?.addSnapshotListener { querySnapshot, firebaseFirestoreException -> contentDTOs.clear() contentUidList.clear() for (snapshot in querySnapshot!!.documents){ var item = snapshot.toObject(ContentDTO::class.java) contentDTOs.add(item!!) contentUidList.add(snapshot.id) } notifyDataSetChanged() } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { var view = LayoutInflater.from(parent.context).inflate(R.layout.item_detail,parent,false) return CustomViewHolder(view) } inner class CustomViewHolder(view: View) : RecyclerView.ViewHolder(view) { } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { var viewholder = (holder as CustomViewHolder).itemView viewholder.detailviewitem_profile_textview.text = contentDTOs!![position].userId Glide.with(holder.itemView.context).load(contentDTOs!![position].imageUrl).into(viewholder.detailviewitem_imageview_content) viewholder.detailviewitem_explain_textview.text = contentDTOs!![position].explain viewholder.detailviewitem_favoritecounter_textview.text = "Likes" + contentDTOs!![position].favoriteCount Glide.with(holder.itemView.context).load(contentDTOs!![position].imageUrl).into(viewholder.detailviewitem_profile_image) } override fun getItemCount(): Int { return contentDTOs.size } }} 이건 MainActivity.kt 코드입니다. package com.example.jbstagram_try1import android.content.Intentimport android.content.pm.PackageManagerimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.view.MenuItemimport androidx.core.app.ActivityCompatimport androidx.core.content.ContextCompatimport com.example.jbstagram_try1.navigation.*import com.example.jbstagram_try1.Rimport com.example.jbstagram_try1.navigation.*import com.google.android.material.bottomnavigation.BottomNavigationViewimport kotlinx.android.synthetic.main.activity_main.*import java.util.jar.Manifestclass MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener { override fun onNavigationItemSelected(p0: MenuItem): Boolean { when (p0.itemId) { R.id.action_home -> { var detailViewFragment = DetailViewFragment() supportFragmentManager.beginTransaction() .replace(R.id.main_content, detailViewFragment).commit() return true } R.id.action_search -> { var gridFragment = GridFragment() supportFragmentManager.beginTransaction().replace(R.id.main_content, gridFragment) .commit() return true } R.id.action_add_photo -> { if (ContextCompat.checkSelfPermission( this, android.Manifest.permission.READ_EXTERNAL_STORAGE ) == PackageManager.PERMISSION_GRANTED ) { startActivity(Intent(this, AddPhotoActivity::class.java)) } return true } R.id.action_favorite_alarm -> { var alarmFragment = AlarmFragment() supportFragmentManager.beginTransaction().replace(R.id.main_content, alarmFragment) .commit() return true } R.id.action_account -> { var userFragment = UserFragment() supportFragmentManager.beginTransaction().replace(R.id.main_content, userFragment) .commit() return true } } return false } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) bottom_navigation.setOnNavigationItemSelectedListener(this) ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE), 1) bottom_navigation.selectedItemId = R.id.action_home }}
- 미해결하울의 안드로이드 인스타그램 클론 만들기
게시글이 뜨지 않습니다.
'상세화면 페이지 만들기' 강의를 공부하는 중입니다. 코드를 그대로 받아적었는데도, 앱을 실행하면 메인화면에 게시글이 뜨지 않습니다. DetailViewFragment.kt 코드를 아래와 같이 작성하였습니다. package com.example.instaclone.navigation import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.example.instaclone.R import com.example.instaclone.navigation.model.ContentDTO import com.google.firebase.firestore.FirebaseFirestore import kotlinx.android.synthetic.main.fragment_detail.view.* import kotlinx.android.synthetic.main.item_detail.view.* class DetailViewFragment : Fragment() { var firestore: FirebaseFirestore? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { var view = LayoutInflater.from(activity).inflate(R.layout.fragment_detail, container, false) firestore = FirebaseFirestore.getInstance() view.detailviewfragment_recyclerview.adapter = DetailViewRecyclerViewAdapter() view.detailviewfragment_recyclerview.layoutManager = LinearLayoutManager(activity) return view } inner class DetailViewRecyclerViewAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() { var contentDTOs: ArrayList<ContentDTO> = arrayListOf() var contentUidList: ArrayList<String> = arrayListOf() init { firestore?.collection("images")?.orderBy("timestamp")?.addSnapshotListener { querySnapshot, firebaseFirestoreException -> contentDTOs.clear() contentUidList.clear() for (snapshot in querySnapshot!!.documents) { var item = snapshot.toObject(ContentDTO::class.java) contentDTOs.add(item!!) contentUidList.add(snapshot.id) } notifyDataSetChanged() } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { var view = LayoutInflater.from(parent.context).inflate(R.layout.item_detail, parent, false) return CustomViewHolder(view) } inner class CustomViewHolder(view: View) : RecyclerView.ViewHolder(view) override fun getItemCount(): Int { return contentDTOs.size } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { var viewholder = (holder as CustomViewHolder).itemView // User Id viewholder.detailviewitem_profile_textview.text = contentDTOs!![position].userId // Image Glide.with(holder.itemView.context).load(contentDTOs!![position].imageUrl).into(viewholder.detailviewitem_imageview_content) // Explain viewholder.detailviewitem_explain_textview.text = contentDTOs!![position].explain // likes viewholder.detailviewitem_favoritecounter_textview.text = "Likes "+ contentDTOs!![position].favoriteCount // ProfileImage Glide.with(holder.itemView.context).load(contentDTOs!![position].imageUrl).into(viewholder.detailviewitem_profile_image) } } }
- 미해결하울의 안드로이드 인스타그램 클론 만들기
글 제거 기능
좋은 강의 감사합니다! 혹시 프로필 사진 제거나 쓴 글,댓글 제거 하는 기능들은 어떤식으로 만들어야 할까요? 내부에서 DTO의 배열이 만들어진 구성이라 삭제하자니 어떤식으로 삭제해야할지 잘 모르겠습니다.