open api 를 이용해서 입력 텍스트가 변경될때마다 학교를 검색하는 예제입니다.
https://www.career.go.kr/cnet/front/openapi/openApiSchoolCenter.do
1. 모델 클래스 (SchoolModel.kt)
data class SchoolModel (
var dataSearch: Datas
)
data class Datas(
var content: List<ConTent>
)
data class ConTent (
var region: String = "",
var estType: String = "",
var schoolName: String = "",
var totalCount: String = "",
var adres: String = "",
var link: String = "",
var campusName: String = "",
var seq: String = "",
var collegeinfourl: String = "",
var schoolType: String = ""
)
2.검색 인터페이스
interface SearchSchool {
@GET("cnet/openapi/getOpenApi.json")
fun getSchool(
@Query("apiKey") apiKey: String,
@Query("svcType") svcType: String,
@Query("svcCode") svcCode: String,
@Query("contentType") contentType: String,
@Query("gubun") text: String,
@Query("searchSchulNm") searchSchulNm: String
): Call<SchoolModel>
@POST("cnet/openapi/getOpenApi.json")
fun getData(
@Field("apiKey") apiKey: String
): Call<SchoolModel>
}
3. 뷰모델
class MainViewModel : ViewModel() {
// TODO: Implement the ViewModel
private var BASE_URL: String = "https://www.career.go.kr/";
var liveData: MutableLiveData<SchoolModel> = MutableLiveData<SchoolModel>()
fun getData(keyword: String) {
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
val api = retrofit.create(SearchSchool::class.java)
val callGetSearchNews = api.getSchool(
"발급받은 api키를 넣으세요.",
"api",
"SCHOOL",
"json",
"univ_list",
keyword
)
callGetSearchNews.enqueue(object : Callback<SchoolModel> {
override fun onResponse(call: Call<SchoolModel>, response: Response<SchoolModel>) {
Log.d("결과", "성공 : ${response.raw()}")
response.body()?.let {
liveData.value=it
}
}
override fun onFailure(call: Call<SchoolModel>, t: Throwable) {
Log.d("결과:", "실패 : $t")
}
})
}
}
4. 메인 프레그먼트
class MainFragment : Fragment() {
companion object {
fun newInstance() = MainFragment()
}
private lateinit var viewModel: MainViewModel
private lateinit var myRecyclerView : RecyclerView
private lateinit var rkeyword : EditText
private lateinit var mAdapter : RecyclerAdapter
private val addressItemList = mutableListOf<ConTent>() // 서버에서 가져온 원본 데이터 리스트
private lateinit var appContext: Context
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
var rootView = inflater.inflate(R.layout.main_fragment, container, false)
myRecyclerView =rootView.findViewById(R.id.recyler);
rkeyword =rootView.findViewById(R.id.keyword);
appContext = requireContext().applicationContext
return rootView;
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
rkeyword.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if(s.toString().isNotEmpty()){
viewModel.getData(s.toString())
}
}
override fun afterTextChanged(s: Editable?) {
}
})
viewModel.liveData.observe(viewLifecycleOwner, listUpdateObserver)
}
private var listUpdateObserver: Observer<SchoolModel> =
Observer {
var contents : List<ConTent> = it.dataSearch.content;
mAdapter = RecyclerAdapter(contents, appContext) // Adapter 생성
myRecyclerView.adapter = mAdapter // 어댑터를 리스트뷰에 세팅
myRecyclerView.layoutManager = LinearLayoutManager(appContext)
// mAdapter.submitList(it)
addressItemList.clear()
addressItemList.addAll(contents)
mAdapter.notifyDataSetChanged()
}
}
5. 어댑터
class RecyclerAdapter(val postList : List<ConTent>, val context : Context)
: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutInflater.from(context)
.inflate(R.layout.list_item,parent ,false))
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(postList[position],context)
}
override fun getItemCount(): Int {
return postList.count()
}
class ViewHolder (itemView: View? ) : RecyclerView.ViewHolder(itemView!!){
private var title = itemView?.findViewById<TextView>(R.id.title)
private var contents = itemView?.findViewById<TextView>(R.id.contents)
fun bind(sdata: ConTent, context: Context){
title?.text = sdata?.schoolName
contents?.text = sdata?.adres
}
}
}
6.메인엑티비티
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
}
}
7.메인레이아웃 (main_acitvity.xml)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" />
8.메인 프래그먼트(main_fragment.xml)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
tools:context=".ui.main.MainFragment">
<EditText
android:id="@+id/keyword"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center_vertical"
android:hint="검색어 입력" android:paddingRight="10dp"
android:paddingLeft="10dp" android:layout_marginRight="110dp"
android:textColor="@color/black" app:layout_constraintRight_toLeftOf="@+id/done"
app:layout_constraintTop_toTopOf="parent">
</EditText>
<Button
android:layout_width="100dp" android:id="@+id/done"
android:layout_height="50dp"
android:layout_marginRight="15dp"
android:text="검색"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
</Button>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyler"
android:layout_width="match_parent" android:layout_marginBottom="10dp"
android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
app:layout_constraintTop_toBottomOf="@+id/keyword">
</androidx.recyclerview.widget.RecyclerView>
</androidx.constraintlayout.widget.ConstraintLayout>
9.리스트뷰(list_item.xml)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="70dp" android:padding="10dp"
android:background="#ffffff"
tools:context=".ui.main.MainFragment">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="20dp"
android:gravity="center_vertical" android:textSize="15dp"
android:textColor="@color/black" android:text="2222"
app:layout_constraintTop_toTopOf="parent">
</TextView>
<TextView
android:id="@+id/contents"
android:layout_width="match_parent"
android:layout_height="30dp" android:textSize="12dp"
android:gravity="center_vertical" app:layout_constraintTop_toBottomOf="@+id/title"
android:textColor="#828282" android:text="1111"
>
</TextView>
</androidx.constraintlayout.widget.ConstraintLayout>
10.결과
'안드로이드' 카테고리의 다른 글
php 다른 테이블의 리스트를 가져오기 (0) | 2022.11.11 |
---|---|
앱 배포시 카카오 로그인 해시키 문제 (0) | 2022.03.30 |
ViewPager2 자동 슬라이드 갤러리 (0) | 2021.06.29 |
안드로이드 11 변경 사항 - READ_PHONE_NUMBERS (0) | 2021.06.29 |
android 11 변경사항 - QUERY_ALL_PACKAGES (0) | 2021.06.29 |