首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android Spannable:如何清除颜色?

Android Spannable:如何清除颜色?
EN

Stack Overflow用户
提问于 2017-08-27 01:22:08
回答 1查看 876关注 0票数 2

我在SearchView for RecyclerView CardViews上设置了一个可扩展的设置。如果在CardView上找到用户输入的文本,则文本将以红色高亮显示.当SearchView行被清除时,我希望CardView文本返回到默认的黑色。当前,文本被清除,颜色错误地保持为红色。我试着在TextView上使用“TextView”,但是没有运气。TextView是"cardBlankText2“。我在这里错过了什么?

代码语言:javascript
复制
RecyclerView Adapter file

private List<ListItem> mListItems;
...    

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_contact_item, parent,false);

    final ItemHolder itemHolder = new ItemHolder(view);    

    return itemHolder;
}

private static class ItemHolder extends RecyclerView.ViewHolder {

    private ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.RED);

    private TextView cardBlankText2; 

    private ItemHolder(View itemView) {
        super(itemView);

        cardBlankText2 = (TextView) itemView.findViewById(R.id.cardBlankText2);
}

    public ForegroundColorSpan getForegroundColorSpan(){
        return foregroundColorSpan;
    }
} 


public void setFilter(List<ListItem> listItems, String searchString) {
    // Note: the String is to get s.toString() from the Main Activity SearchView.
    // Note the plural for listItems.
    mListItems = new ArrayList<>();
    mListItems.addAll(listItems);
    this.searchString = searchString;
    notifyDataSetChanged();
}

public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {

    final ListItem listItem = mListItems.get(position);


    String todoHighlight = listItem.getTodo().toLowerCase(Locale.getDefault());
    String note1Highlight = listItem.getNote1().toLowerCase(Locale.getDefault());

    // Set up the logic for the highlighted text
    int todoStartPos = todoHighlight.indexOf(searchString);
    int todoEndPos = todoStartPos + searchString.length();
    int note1StartPos = note1Highlight.indexOf(searchString);
    int note1EndPos = note1StartPos + searchString.length();
    Spannable spanString2 = Spannable.Factory.getInstance().newSpannable(
            itemHolder.cardBlankText2.getText());        

    if (todoStartPos != -1 && searchString.length() > 0 && todoHighlight.contains(searchString)) {
        spanString2.setSpan(new ForegroundColorSpan(Color.RED), todoStartPos, todoEndPos,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        itemHolder.cardBlankText2.setText(spanString2);
    }
    **else if (searchString.length() == 0) {
        spanString2.removeSpan(itemHolder.cardBlankText2.getText());
        itemHolder.cardBlankText2.setText(spanString2);
    }**
}


MainActivity

public class MainActivity extends AppCompatActivity {

...
@Override
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.cardview_menu, menu);

    final MenuItem searchItem = menu.findItem(R.id.action_search);

    searchItem.setVisible(true);

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

    final SearchView mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    final EditText mSearchEditText = (EditText) mSearchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);

        mSearchEditText.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {                
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {                    
            }

            @Override
            public void afterTextChanged(Editable s) {


                final ArrayList<ListItem> filteredModelList2 = filter(allList, s.toString());

                if (!mSearchView.isIconified() && filteredModelList2.size() == 0) {

                        // re-load the list so the Adapter refreshes the RecyclerView list View.
                        adapter.clear();
                        adapter.addAll(allList);
                } else if (!mSearchView.isIconified() && filteredModelList2.size() > 0) {                            
                        adapter.setFilter(filteredModelList2, s.toString());
                        mRecyclerView.scrollToPosition(0);
                }
        });
        return super.onCreateOptionsMenu(menu);
    }  

// Do Search filtering from MainActivity's OnQueryTextChange(String newText)
// The Spannable code is in the onBindVH section for the itemHolders.
public ArrayList<ListItem> filter(List<ListItem> listItems, String query) {

    query = query.toLowerCase();

    final ArrayList<ListItem> filteredModelList = new ArrayList<>();
    for (ListItem listItem : listItems) {
        final String text = listItem.getTodo().toLowerCase();
        final String text2 = listItem.getNote1().toLowerCase();
        final String text3 = listItem.getNote2().toLowerCase();
        if (text.contains(query) || text2.contains(query) ||
            text3.contains(query)) {
            filteredModelList.add(listItem);
        }
    }
    return filteredModelList;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-27 07:24:44

方法removeSpan()是指setSpan()的反向操作,因此您应该将它们都传递给相同的对象。要实现这一点,请将ForegroundColorSpan作为ViewHolder的一个字段(见下文)

代码语言:javascript
复制
public void onBindViewHolder(final MyViewHolder itemHolder, int position) {
    String todoHighlight = mListItems.get(position).getTodo();
    itemHolder.cardBlankText2.setText(todoHighlight);

    // Set up the logic for the highlighted text
    int todoStartPos = todoHighlight.indexOf(searchString);
    int todoEndPos = todoStartPos + searchString.length();

    // ... skipped some lines ...

    Spannable spanString2 = Spannable.Factory.getInstance().newSpannable(
        itemHolder.cardBlankText2.getText());        

    if (todoStartPos != -1 && searchString.length() > 0 && todoHighlight.contains(searchString)) {
        spanString2.setSpan(itemHolder.getForegroundColorSpan(), todoStartPos, todoEndPos,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        itemHolder.cardBlankText2.setText(spanString2);
    }
    else if (searchString.length() == 0) {
            spanString2.removeSpan(itemHolder.getForegroundColorSpan());
            itemHolder.cardBlankText2.setText(spanString2);
    }
}

ViewHolder:

代码语言:javascript
复制
class MyViewHolder extends RecyclerView.ViewHolder{
    private ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.RED);

    public MyViewHolder(View itemView){
        super(itemView);
    }

    public ForegroundColorSpan getForegroundColorSpan(){
        return foregroundColorSpan;
    }
}

编辑远程调试是困难的,所以让我们用另一种方式来做,MCVE风格:请使用以下代码,运行它,如果它有效(比如“根据搜索文本突出显示更改”),那么您就走得更远了。

代码语言:javascript
复制
public class Activity8_RecyclerViewGrid extends AppCompatActivity
{
    private int counter = 0;
    private static String[] searchTexts = new String[]{"rem", "ia", "", "ol" };

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity8__recycler_view);

        RecyclerView rcv = (RecyclerView)findViewById(R.id.recyclerView);
        rcv.setLayoutManager(new GridLayoutManager(this, 2));
        final MyAdapter adapter = new MyAdapter(allMyWords());
        rcv.setAdapter(adapter);

        final TextView tvSearchText = (TextView)findViewById(R.id.tvSearchText);

        Button btnFilter = (Button)findViewById(R.id.btnFilter);
        btnFilter.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                String searchString = searchTexts[counter%4];
                adapter.setFilter(Activity7_GridViewStuff.allMyBooks(), searchString);
                tvSearchText.setText(searchString);
                counter++;
            }
        });
    }


    public static ArrayList<String> allMyWords()
    {
        String[] theLoremArray = null;
        String LOREM_STRING = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";
        String[] sTemp = LOREM_STRING.split(" ");
        StringBuilder sb = new StringBuilder();

        theLoremArray = new String[sTemp.length/3];
        for (int i = 0; i < (sTemp.length - sTemp.length%3); i++)
        {
        sb.append(sTemp[i]).append(" ");
        if (i%3 == 2)
        {
            theLoremArray[i/3] = sb.toString();
            //  Log.d(TAG, "mLoremArray [" + i / 3 + "] = " + sb.toString());
            sb.delete(0, sb.length());
        }
    }

    ArrayList<String> words = new ArrayList<>();

    for (int i = 0; i < theLoremArray.length; i++)
        {
            words.add( theLoremArray[i]);
        }
        return words;
    }

    class MyAdapter extends RecyclerView.Adapter<MyHolder>{

        private List<String> data;
        private String searchString = "";

        MyAdapter(List<String> data){
            this.data = data;
        }

        public void setFilter(List<String> listItems, String searchString){
          //  data = new ArrayList<>();
          //  data.addAll(listItems);
            this.searchString = searchString;
            notifyDataSetChanged();
        }

        @Override
        public MyHolder onCreateViewHolder(ViewGroup parent, int viewType)
        {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity8_grid_cell, null);
            return new MyHolder(v);
        }

        @Override
        public void onBindViewHolder(final MyHolder holder, int position)
        {
            holder.text.setText(data.get(position));
            String todoHighlight = data.get(position);

            // Set up the logic for the highlighted text
            int todoStartPos = todoHighlight.indexOf(searchString);
            int todoEndPos = todoStartPos + searchString.length();

            Spannable spanString2 = Spannable.Factory.getInstance().newSpannable(holder.text.getText());

            if(todoStartPos != -1 && searchString.length() > 0 && todoHighlight.contains(searchString)){
                spanString2.setSpan(holder.getForegroundColorSpan(),    todoStartPos, todoEndPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            else if (searchString.length() == 0){
                spanString2.removeSpan(holder.getForegroundColorSpan());
            }

            holder.text.setText(spanString2);
        }

        @Override
        public int getItemCount()
        {
        return data.size();
        }
    }

    class MyHolder extends RecyclerView.ViewHolder{

        private ForegroundColorSpan foregroundColorSpan = new   ForegroundColorSpan(Color.CYAN);
        TextView text;

        public MyHolder(View itemView){
            super(itemView);
            text = (TextView) itemView.findViewById(R.id.lorem_text);
        }

        public ForegroundColorSpan getForegroundColorSpan(){
            return foregroundColorSpan;
        }
    }
}

activity8_recycler_view.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.samples.Activity8_RecyclerViewGrid">

    <TextView
        android:id="@+id/tvSearchText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:textAppearance="@style/Base.TextAppearance.AppCompat.Title"
        android:textColor="#ff0000" />

    <Button android:id="@+id/btnFilter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="SET NEW FILTER"
        android:layout_gravity="center_horizontal" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="80dp">

    </android.support.v7.widget.RecyclerView>
</FrameLayout>

activity8_grid_cell.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent">
    <TextView
        android:id="@+id/lorem_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginEnd="16dp"
        android:textAppearance="?android:attr/textAppearanceLarge" />
</FrameLayout>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45900950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档