본문 바로가기
Android

android Spannable을 이용한 TextView에 버튼 만들고 버튼을 클릭하면 선택한 Spannable만 제거

by leopard4 2023. 3. 24.

 

 

 

결론 : Spannable의 클릭 빌드할때 오버라이딩한 클릭메소드를 적용해서 해결했다.

주석부분은 시행착오 참고용

void getAlcoholNetworkData() {

        Retrofit retrofit = NetworkClient.getRetrofitClient(MyRecipeWriteSecondActivity.this);

        CreatingApi api = retrofit.create(CreatingApi.class);

        SharedPreferences sp = getSharedPreferences(Config.PREFERENCE_NAME, MODE_PRIVATE);
        String accessToken = "Bearer " + sp.getString(Config.ACCESS_TOKEN, "");

        offset = 0;
        count = 0;

        Call<AlcoholList> call = api.getAlcoholList(accessToken, alcoholKeyword ,offset, limit);
        call.enqueue(new Callback<AlcoholList>() {
            @Override
            public void onResponse(Call<AlcoholList> call, Response<AlcoholList> response) {

                alcoholList.clear();

                if (response.isSuccessful()) {

                    count = response.body().getCount();
                    offset = offset + count;
                    alcoholList.addAll(response.body().getResult());
                    alcoholAdapter = new AlcoholAdapter(MyRecipeWriteSecondActivity.this, alcoholList);
                    alcoholAdapter.setOnItemClickListener(new AlcoholAdapter.onItemClickListener() {
                        @Override
                        public void onItemClick(int index) {
//                            selectedAlcoholList.add(alcoholList.get(index).getName());

                            if (selectedAlcoholList.size() == 10) {
                                Snackbar.make(findViewById(R.id.alcoholRecyclerView), "재료는 10개까지만 추가할 수 있습니다.", Snackbar.LENGTH_SHORT).show();
                            }else {
                                if (txtAlcohol.getText().toString().contains(alcoholList.get(index).getName())) {
                                    Snackbar.make(findViewById(R.id.alcoholRecyclerView), "이미 추가된 재료입니다.", Snackbar.LENGTH_SHORT).show();
                                } else {
                                    selectedAlcoholList.add(alcoholList.get(index).getName());
                                    txtAlcohol.setText(txtAlcohol.getText().toString() + alcoholList.get(index).getName() + ", ");
                                    Log.i("selectedAlcoholList", selectedAlcoholList.toString());
                                    // Get the current text of the TextView
                                    SpannableStringBuilder builder = new SpannableStringBuilder(txtAlcohol.getText());

                                    // Iterate through the list of words and set the ClickableSpan on each one
                                    for (String word : selectedAlcoholList) {
                                        Log.i("word", word);
                                        int startIndex = builder.toString().indexOf(word);
                                        Log.i("startIndex", String.valueOf(startIndex));
                                        int endIndex = startIndex + word.length()+1;
                                        Log.i("endIndex", String.valueOf(endIndex));
                                        builder.setSpan(new WordClickableSpan(word, txtAlcohol), startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                                    }

                                    // Update the TextView with the modified text
                                    txtAlcohol.setText(builder);
//                                    String s = alcoholList.get(index).getName() + ", ";
//                                    SpannableStringBuilder spannable = new SpannableStringBuilder(txtAlcohol.getText()); // 기존 텍스트를 SpannableStringBuilder의 기본으로 사용
//                                    int start = spannable.length(); // Get the start position for the new spannable text
//                                    spannable.append(s); // 기존 텍스트에 새 텍스트 추가
//                                    ClickableSpan clickableSpan = new ClickableSpan() {
//                                        @Override
//                                        public void onClick(View view) {
////                                            int wordStart = spannable.toString().indexOf(s, start); // Use start position to find the clicked word
//                                            int wordStart = spannable.toString().indexOf(s);
//                                            int wordEnd = wordStart + s.length(); // Get the end position for the clicked word
//                                            spannable.delete(wordStart, wordEnd); // Remove clicked word from SpannableStringBuilder
//                                            Log.i("스팬", spannable.toString());
//                                            Log.i("에스", s);
//                                            Log.i("인덱스", index + "");
//                                            Log.i("스타트", start + "");
//                                            Log.i("알콜리스트겟인덱스",alcoholList.get(index).getName() + "");
//
////                                            I/스팬: 신선주 약주16, 한청, 33JU 25도, 매화수,
////                                            I/에스: 업타운 피나콜라다 750ml,
////                                            I/인덱스: 8
////                                            I/스타트: 29
////                                            I/알콜리스트겟인덱스: 업타운 피나콜라다 750ml
////                                            I/스팬:
////                                            I/에스: 신선주 약주16,
////                                            I/인덱스: 4
////                                            I/스타트: 0
////                                            I/알콜리스트겟인덱스: 신선주 약주16
//                                            // 검색햇을경우 인덱스가 동일하기 때문에 인덱스로 지우는것은 안됨.
//                                            Log.i("비포셀렉티드알콜리스트", selectedAlcoholList.toString());
//                                            selectedAlcoholList.removeIf(selectedAlcoholList -> selectedAlcoholList.equals(s.replace(", ", ""))); // api24 이상에서만 사용가능
//                                            Log.i("애프터셀렉티드알콜리스트", selectedAlcoholList.toString());
//                                            Log.i("애프터셀렉티드알콜리스트사이즈", selectedAlcoholList.size() + "");
//                                            Log.i("애프터셀렉티드알콜리스트사이즈", selectedAlcoholList.equals(s.replace(", ", "")) + "");
//
//
//                                            txtAlcohol.setText(spannable); // Update TextView with modified SpannableStringBuilder
//                                            updateTxtAlcoholCount(); // Update txtAlcoholCount with the new count
//                                        }
//                                    };
//                                    spannable.setSpan(clickableSpan, start, start + s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // Add the new ClickableSpan to the SpannableStringBuilder
//                                    txtAlcohol.setText(spannable); // Update TextView with the modified SpannableStringBuilder
                                    txtAlcohol.setMovementMethod(LinkMovementMethod.getInstance()); // Make the text clickable

                                    updateTxtAlcoholCount(); // Update txtAlcoholCount with the new count
//                                    txtAlcohol.setText((txtAlcohol.getText().toString()) + (alcoholList.get(index).getName() + ", "));
//                                    selectedAlcoholList.add(alcoholList.get(index));
//                                    txtAlcoholCount.setText(selectedAlcoholList.size() + "개");
                                }

                            }


                        }


                    });
                    alcoholRecyclerView.setAdapter(alcoholAdapter);
                }
            }
            @Override
            public void onFailure(Call<AlcoholList> call, Throwable t) {


            }
        });

    }
    private class WordClickableSpan extends ClickableSpan {
        private String word;
        private TextView textView;

        public WordClickableSpan(String word, TextView textView) {
            this.word = word;
            this.textView = textView;
        }

        @Override
        public void onClick(View widget) {
            // TextView의 현재 텍스트 가져오기
            SpannableStringBuilder builder = new SpannableStringBuilder(textView.getText());

            // 클릭한 단어의 시작 및 끝 인덱스 찾기
            int startIndex = builder.toString().indexOf(word);
            int endIndex = startIndex + word.length()+1;

            // 클릭한 단어를 텍스트에서 제거
            builder.delete(startIndex, endIndex+1);
            // 클릭한 단어를 리스트에서 제거
            selectedAlcoholList.removeIf(selectedAlcoholList -> selectedAlcoholList.equals(word.replace(", ", "")));

            // 수정된 텍스트로 TextView 업데이트
            textView.setText(builder);
            updateTxtAlcoholCount();
        }
    }