Change TextView to clickable words in a custom ListView

时间:2016-08-31 12:06:23

标签: java android listview spannable

I have a custom List in which different buttons are present on each List. my aim is to make a single text view

    <TextView
    android:id="@+id/text"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="#000000"
    android:text="Example"
    android:textSize="16dp"
    android:layout_below="@+id/rl1" />

to be change as per the Sentence so that each word is clickable From enter image description here
To thisenter image description here
And Word to be passed onto a Function.

I am thinking if we can divide single TextView to multiple TextView and make them clickable is that possible NON XML solution?
Any snippet will be thankful
Regards

3 个答案:

答案 0 :(得分:3)

Please try this code because you need Spannable string:

     SpannableString ss = new SpannableString("Hello World");
        ClickableSpan span1 = new ClickableSpan() {
            @Override
            public void onClick(View textView) {
                // do first word click work
            }
        };

        ClickableSpan span2 = new ClickableSpan() {
            @Override
            public void onClick(View textView) {
                // do second word click work
            }
        };

        ss.setSpan(span1, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(span2, 6, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        TextView textView = (TextView) findViewById(R.id.hello);
        textView.setText(ss);
        textView.setMovementMethod(LinkMovementMethod.getInstance());

Thanks

答案 1 :(得分:1)

您的问题需要深入使用SpannableString, Androider 已经提供了一个很好的解决方案来解决您的问题,但您说您正在从数据库中动态获取单词,所以我在这里编写了一个代码你将处理动态内容。我没有测试过这个,希望它适合你。

MainActivity.java:

    public class MainActivity extends AppCompatActivity {

    ListView lv ;
    public static String [] prgmNameList={"Android Dev","SpearHead Inc"}; // You can put dynamic strings in this array .
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        lv=(ListView) findViewById(R.id.listView);
        lv.setAdapter(new CustomAdapter(this, prgmNameList));

    }


}

CustomAdapter:

public class CustomAdapter extends BaseAdapter {
    String [] result;
    Context context;
    private static LayoutInflater inflater=null;
    public CustomAdapter(MainActivity activity, String[] prgmNameList) {

        result = prgmNameList;
        context = activity;
        inflater = ( LayoutInflater )context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    @Override
    public int getCount() {
        return result.length;
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public class Holder
    {
        TextView tv;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        Holder holder=new Holder();
        View rowView = inflater.inflate(R.layout.list_item, null);
        holder.tv=(TextView) rowView.findViewById(R.id.textView1);
        //holder.tv.setText(result[position]);

        String span[] = result[position].split(" ") ;

        SpannableString ss = new SpannableString(result[position]);

        ClickableSpan spans[] = new ClickableSpan[span.length];

        for(int spanCount = 0 ; spanCount < span.length ; spanCount++){
            spans[spanCount] = new ClickableSpan() {
                @Override
                public void onClick(View textView) {

                    TextView v = (TextView)textView ;
                    String text = v.getText().toString() ;

                    Log.d("View" , text);
                }
            };
        }

        int start = 0 ;
        int end ;
        try {
            for(int spanCount = 0 ; spanCount < span.length ; spanCount++){
                end = span[spanCount].length()-1 ;
                ss.setSpan(spans[spanCount], start, end , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                start = span[spanCount].length()+1;
                end = span[spanCount].length() + 2 + end ;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        holder.tv.setText(ss);

        Log.d("SpannableString" , ss.toString());

        return rowView;
    }

}

list_item.xml:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

    <TextView
        android:id="@+id/textView1"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25dp"

        android:text="Hello World" />

</LinearLayout>

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.shishupalshakya.spannablestringsample.MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </ListView>


</RelativeLayout>

将以上代码嵌入应用程序并运行。

答案 2 :(得分:0)

I have made a simple example which satifes your requirements

SpannableString text = new SpannableString("Text with Clickable word");  

// make "Clickable" (characters 10 to 18) display a toast message when touched  
final Context context = this;  
ClickableSpan clickableSpan = new ClickableSpan() {  
    @Override  
    public void onClick(View view) {  
        Toast.makeText(context, "Clicked!!!", Toast.LENGTH_LONG).show();  
    }  
};  
text.setSpan(clickableSpan, 10, 18, 0);  

According to your updated answer

  1. You can use contains method on string to find out whether your DB`s words are present or not in the available string
  2. then you can use indexOf to get their index in available string
  3. you already have the length of the word

so you can make this process dynamic easily