홈>
recyclerView를 추가하기 전에 두 번 확인한 retrofit 라이브러리를 사용하여 응답을 가져 왔으며 정상적으로 작동하지만 recyclerView 및 어댑터를 추가 한 후 데이터가 표시되지 않습니다.
ApiService.kt
package com.kunalrai.githubtrends
import com.squareup.moshi.Moshi
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import retrofit2.http.GET
private const val BASE_URL = "https://github-trending-api.now.sh"
val moshi: Moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
private val retrofit = Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.baseUrl(BASE_URL)
.build()
interface ApiService {
@GET("repositories")
fun getRepos(): Call<List<Repo>>
}
object Api {
val RETROFIT_SERVICE : ApiService by lazy { retrofit.create(ApiService::class.java) }
}
ListAdapter.kt
package com.kunalrai.githubtrends
import android.content.Context
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
class ListAdapter(private val context: Context?, private val repoList: List<Repo>) : RecyclerView.Adapter<ListAdapter.MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.repo_item,parent,false)
return MyViewHolder(view)
}
override fun getItemCount(): Int {
Log.i("reposize: ",""+repoList.size)
return repoList.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.author.text = repoList[position].author
holder.repo.text = repoList[position].name
Glide.with(context!!).load(repoList[position].avatar)
.apply(RequestOptions().centerCrop())
.into(holder.image)
}
class MyViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView!!) {
val author: TextView = itemView!!.findViewById(R.id.owner_name)
val image: ImageView = itemView!!.findViewById(R.id.owner_image)
val repo: TextView = itemView!!.findViewById(R.id.repo_name)
}
}
ListViewModel.kt
package com.kunalrai.githubtrends
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class ListViewModel : ViewModel() {
var repoList: MutableLiveData<List<Repo>> = MutableLiveData(listOf())
fun getRepos(): MutableLiveData<List<Repo>>{
repoList = MutableLiveData()
loadRepos()
return repoList
}
private fun loadRepos() {
Api.RETROFIT_SERVICE.getRepos().enqueue( object: Callback<List<Repo>> {
override fun onFailure(call: Call<List<Repo>>, t: Throwable) {
Log.i("Failure: ", t.message)
}
override fun onResponse(call: Call<List<Repo>>, response: Response<List<Repo>>) {
if(response.body() != null){
repoList.value = response.body()
Log.i("response.body :",""+response.body())
}
}
})
}
}
ListFragment.kt
package com.kunalrai.githubtrends
import androidx.lifecycle.ViewModelProviders
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.kunalrai.githubtrends.databinding.ListFragmentBinding
class ListFragment : Fragment() {
companion object {
fun newInstance() = ListFragment()
}
private val viewModel: ListViewModel by lazy {
ViewModelProviders.of(this).get(ListViewModel::class.java)
}
private lateinit var binding: ListFragmentBinding
var recyclerView: RecyclerView? = null
lateinit var listAdapter: ListAdapter
var repoList: List<Repo> = listOf()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// viewModel.getRepos().observe(this,
// Observer<List<Repo>> {
// it?.let { repoList ->
// this.repoList = repoList
// Log.i("inside observe",""+repoList)
// }
// })
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.getRepos().observe(this,
Observer<List<Repo>> {
it?.let { repoList ->
this.repoList = repoList
Log.i("inside observe",""+repoList)
listAdapter = ListAdapter(context, repoList)
recyclerView?.adapter = listAdapter
}
})
recyclerView = view.findViewById(R.id.rv_repo_list)
recyclerView?.layoutManager = LinearLayoutManager(context)
recyclerView?.setHasFixedSize(true)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = ListFragmentBinding.inflate(inflater, container, false)
binding.lifecycleOwner
binding.viewmodel = viewModel
setHasOptionsMenu(true)
// recyclerView = view?.findViewById(R.id.rv_repo_list)
// recyclerView?.layoutManager = LinearLayoutManager(context)
// recyclerView?.setHasFixedSize(true)
// listAdapter = ListAdapter(context, repoList)
// recyclerView?.adapter = listAdapter
return binding.root
}
}
Repo.kt
package com.kunalrai.githubtrends
import com.squareup.moshi.Json
data class Repo(
@Json(name = "author")
var author: String,
@Json(name = "name")
var name: String,
@Json(name = "description")
var desc: String,
@Json(name = "avatar")
var avatar: String,
@Json(name = "language")
var language: String,
@Json(name = "url")
var url: String,
@Json(name = "stars")
var stars: String,
@Json(name = "forks")
var forks: String
)
list_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewmodel"
type="com.kunalrai.githubtrends.ListViewModel" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ListFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_repo_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</layout>
repo_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/owner_image"
android:layout_width="96dp"
android:layout_height="96dp"
app:civ_border_width="2dp"
app:civ_border_color="#FF000000"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/owner_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/repo_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Logcat :
2019-11-29 19:15:15.170 20890-20890/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2019-11-29 19:15:15.187 20890-20890/? E/Zygote: accessInfo : 1
2019-11-29 19:15:18.090 20890-20890/com.kunalrai.githubtrends E/RecyclerView: No adapter attached; skipping layout
매니페스트 파일에서 인터넷 권한을 부여했습니다. recyclerView를 추가하기 전에 가져온 응답을 확인했습니다.
빈 화면은 충돌없이 출력됩니다.
- 답변 # 1
- 답변 # 2
BASE_URL은
/
로 끝나야합니다. 그래서/
를 추가하십시오 기본 URL의 끝BASE_URL = "https://github-trending-api.now.sh/"
repoList를 초기화했기 때문에 API가 호출되지 않고 null 인 경우 api를 호출했습니다. api는 전화하지 않으므로 원치 않는 경우를 제거하십시오
var repoList: MutableLiveData<List<Repo>> = MutableLiveData(listOf()) if(repoList == null) { repoList = MutableLiveData() loadRepos() }
onviewCreated ()에서 API 호출
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.getRepos().observe(this, Observer<List<Repo>> { it?.let { repoList -> listAdapter = ListAdapter(context, repoList) recyclerView?.adapter = listAdapter } }) }
관련 자료
- java - EclEmma 및 Eclipse를 사용하여 "범위 데이터가 수집되지 않았습니다"메시지 받기
- PowerShell의 레지스트리 키를 사용하여 소프트웨어 설치, 일부 소프트웨어 이름이 표시되지 않음
- Laravel의 원시 쿼리를 사용하여 SQL 데이터베이스에서 특정 열 가져 오기
- javascript - XMLHttpRequest를 사용할 때 내 결함 URL에 대해 ERR_CERT_COMMON_NAME_INVALID를 얻습니까?
- PowerShell에서 레지스트리 키를 사용하여 소프트웨어 버전 가져 오기
- Azure DevOps에서 PowerShell을 사용하여 SQLAzure에서 데이터베이스 이름 가져 오기
- SPARK SQL에서 weekofyear와 date_format을 사용하여 다른 출력 얻기
- python - 상태 머신을 사용하여 파이 게임에서 지속적인 움직임 얻기
- java - 문자열 수식을 전달하여 ScriptEngineManager를 사용할 때 오류가 발생하는 이유는 무엇입니까?
- powerquery - dax - userelationship 사용 및 순환 종속성 감지 오류 발생
- python - PySpark의 열 조건을 사용하여 Null 값이 대체되지 않음
- python - Keras에서 CNN 모델을 사용하여 상당히 나쁜 정확도 얻기
- node.js - https의 경우 reqget ( 'Referrer')를 사용하여 전체 경로를 가져 오지 않음
- 파이썬에서 인덱스 함수를 사용하지 않고 목록에서 다음 요소 가져 오기
- python - 상속 된 클래스를 사용할 때 AttributeError 받기
- 파이썬을 사용하여 JSON 형식의 PDF 데이터를 얻지 못합니까?
- command line - 명령 줄 및 grep을 사용하여 nslookup을 사용하여 DNS에서 EKS 서비스 IP 주소 가져 오기
관련 질문
- ViewModel (Android Studio, Kotlin)을 사용하여 조각 A에서 조각 B로 데이터 보내기
- android : 조각에서 "lateinit 바인딩"을 초기화하는 방법은 무엇입니까?
- java : 조각 Android에서 조각 열기
- android : NavigationUI의 동일한 호스트 활동에서 데이터 전달 및 조각 텍스트 /버튼 업데이트
- Android 탐색 java.language.IllegalStateException 조각 클래스가 설정되지 않았습니다.
- android : 리사이클 러 어댑터에서 조각으로 모션 이벤트 및 데이터 전달
- java : Android의 sqlite 쿼리에서 sqrt 함수를 사용하는 방법
- Android : Kotlin을 사용하여 LinearLayout의 배경 흐림
- android : pagingData 3 흐름을 다른 흐름과 결합
- android : 보기 용 Kotlin 합성 확장
몇 가지 변경을 권장합니다.
ListAdapter에서
그런 다음 조각에