class SearchActivity : AppCompatActivity() {
private lateinit var adapter: Rc_Adapter
private lateinit var location_name: String
private lateinit var rp1: String
private lateinit var rp2: String
private lateinit var rp3: String
private lateinit var am: AssetManager //경로: 에셋의 경로는 일반 경로와 다르게 선언한다.
private var bufrd: BufferedReader? = null
private lateinit var inst: InputStream //파일 리더 선언: 파일을 오픈하여, 파일클래스 얻어, 파일 클래스의 함수들을 이용하여 파일을 다루는 것이 목적이다. //asset에 저장된 파일들은 InputStream으로만 오픈 가능하다.
private lateinit var tx: String
private lateinit var text: String //문자열로된 파일의 문자열을 읽어와서 저장하기 위해 선언해주는 프로퍼티다. 이 저장된 값은, 텍스트 뷰 객체의 텍스트 속성값에 대입된다.
private lateinit var arraystr: ArrayList<VO>
private lateinit var arraystr2: ArrayList<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search)
am = resources.assets //경로: 에셋의 경로는 일반 경로와 다르게 선언한다.
search_btn.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
for (i in 1..2) {
when (i) {
1 -> {
rp1 = "구약"
for (o in 1..39) {
when (o) {
1 -> {
rp2 = "1. 창세기"
for (p in 1..50) {
when (p) {
p -> {
rp3 = "genesis$p"
memem("창세기", p)
}
}
}
}
.............중략
fun memem (book: String, chapter: Int) {
location_name = "$rp1/$rp2/$rp3.txt"
try {
inst = am.open(location_name)
//★★★권/장/절을 선택할 때에, when문으로 처리하자. 리사이클러뷰의 버튼 중 어느 인덱스에 해당하는 버튼을 누르는지에 따라, 해당 "장"을 오픈해주자. 그러므로 인덱스값을 when문의 매개변수에 인수로써 보내어 대입해주자.
//inst = am.open("구약/1. 창세기/genesis1.txt") //여기가 시작지점: 파일을 여는 과정에서 리턴되는 파일 핸들(Handle) 확보, 오픈할 파일이 없으면, catch문을 실행하여 예외상황에 대비한다.
bufrd = BufferedReader(InputStreamReader(inst))
//val textView = view.findViewById<View>(R.id.txtRead) as TextView // 텍스트 뷰 객체를 생성한다.
//리사이클러뷰에 절에 대한 데이터를 대입해주고, 장 절에 대한 리사이클러뷰 목록을 만들어주고, 클릭 이벤트를 구현해준 후, 각 버튼의 포지션 값을 받아, 이 값을 오픈의 when문의 매개변수에 인수로 보내주자.
for(i in 1..200) {
when(i) {
i -> {
if ((bufrd!!.readLine().also { tx = it }) != null) {
text = tx.toString() //바이너리를 바이트 형식의 문자열로 바꿔서 텍스트 뷰 객체에 대입해준다.
arraystr2.add(text)
//ry_desc.text = text //텍스트 뷰에 읽어들인 텍스트들을 대입한다.
//addItem(i.toString(), text) //이거 괄호 안에서 옆으로 추가해야지, 밑에다가 새로 addItem하면 오류나...
//store = text //여기로 포지션 값을 가져오자.
//버퍼리드로 읽어온 한 줄의 텍스트 중에서, 원하는 문자열을 찾아주는 코드다.
if (arraystr2.contains(editT1.text.toString()) == true) {
addItem("[${book}: ${chapter}장${i}절]", text)
}
arraystr2.clear()
}
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
try {
bufrd?.close()
inst.close()
} catch (e: Exception) {
e.printStackTrace()
}
adapter = Rc_Adapter(arraystr) <-★★바로 여기가 833번줄 에러가 나는 곳입니다.
rv_search.setAdapter(adapter)
adapter.notifyDataSetChanged()
}
//리사이클러뷰 어댑터에 implement Filterable
class Rc_Adapter (var mem: ArrayList<VO>) : RecyclerView.Adapter<Rc_Adapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v: View = LayoutInflater.from(parent.context).inflate(R.layout.activity_search_item, parent, false)
return ViewHolder(v)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val memi = mem[position]
holder.itemView.search_item1.setText(memi.getTitle())
holder.itemView.search_item2.setText(memi.getDesc())
}
override fun getItemCount(): Int {
return mem.size
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
}
}
fun addItem (bcv: String, contents: String) {
val dataC = VO()
dataC.setTitle(bcv)
dataC.setDesc(contents)
arraystr.add(dataC)
}
}
class VO {
//private var icon: Drawable? = null
private var title: String? = null
private var desc: String? = null
//그러면 변수를 선언할 때에도, 얼마나 많은 변수가 필요해질지 모르겠다... 데이터 나열 형태의 변수는 없을까? 데이터를 대입해주면, 스스로 판단하고, 변수를 새로 생성하는 것이다.
//코딩 아이디어: 겟과 셋을 하나만 선언해보자. 그리고, 그 내부에, 조건문을 배치해서, icon이라 명시하지 말고, 미지수로 두자. 어느 형태의 데이터든지 받아서 셋하고, 겟 할 수 있는 형식으로 만들어야 한다.
/*fun getIcon(): Drawable? {
return icon
}
fun setIcon(icon: Drawable?) {
this.icon = icon
}*/
fun getTitle(): String? {
return title
}
fun setTitle(title: String?) {
this.title = title
}
fun getDesc(): String? {
return desc
}
fun setDesc(desc: String?) {
this.desc = desc
}
}
kotlin.UninitializedPropertyAccessException: lateinit property arraystr has not been initialized
at com.example.yhw.SearchActivity.memem(SearchActivity.kt:833)<-- ★이거랑
at com.example.yhw.SearchActivity$onCreate$1.onClick(SearchActivity.kt:56)<-- ★이것입니다.
at android.view.View.performClick(View.java:7352)
at android.widget.TextView.performClick(TextView.java:14230)
at android.view.View.performClickInternal(View.java:7318)
at android.view.View.access$3200(View.java:846)
at android.view.View$PerformClick.run(View.java:27800)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
제가 만드려고 하는 기능은, 검색 기능인데요. 사용자가 특정 단어가 포함된 구절을 찾고자 할 때에,
사용자가 입력한 단어를 파일리더로 읽어온 텍스트 한 줄 속에서 contains()함수로 찾아내어,
특정 단어가 포함된 구절을 배열 변수에 담아놓고, 이 배열 변수의 데이터들을 리사이클러뷰의 어댑터
클래스로 보내어, 화면에 리스트 형식으로 출력시켜주려고 했습니다만,
arraystr이라는 배열 변수가 초기화가 되지 않았다고 뜨는 것으로보아,
아무래도 contains()함수를 제가 사용할 줄 모르는게 아닌가 싶습니다.
하지만, 책에서 가르쳐주기를, 배열 변수에 담긴 데이터 중에, 원하는 문자열을 갖은 데이터를 찾으면,
true를 반환해준다기에 저렇게 코딩한 것인데.. 안되네요...
그리고 for문이랑 when문 섞어가면서, 원하는 기능이 수행되도록 코딩해놓긴 했는데...
이 조건문 보다 더 좋은 방식이 아무래도 있을것 같다는 느낌이 듭니다. 조언좀 부탁드립니다. ^^;