0

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

phpdroid
  • 1,642
  • 1
  • 18
  • 36

3 Answers3

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

Androider
  • 3,833
  • 2
  • 14
  • 24
  • my words are dynamic from database not first or second words – phpdroid Aug 31 '16 at 12:21
  • This is just an example, it's your job to figure out how to use this dynamically – ElefantPhace Aug 31 '16 at 12:36
  • @ElefantPhace i have checked this code in my research before posting this ques. this is not closely related to be working on a custom ListView – phpdroid Aug 31 '16 at 12:39
  • @phpdroid, I'll also try to figure out your problem, give me some time. – Androider Aug 31 '16 at 12:46
  • @phpdroid, I think you have to use arraylist of your dynamic data from database and then to set span, fetch string sentence from array position and split into words and then set clickable string as per length. Do this in loop dynamically or getview method of listview (just and example) as suits to you. But it's a difficult job and basically spannable tree is used only somewhere to open a web hyperlink. – Androider Aug 31 '16 at 12:57
1

Your question requires deep use of SpannableString , Androider has already provided a good hint to solve your problem , but you said that you are getting words dynamically from database , so here I have written a code for you which will process dynamic content. I have not tested this , Hope it should work for you .

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>

Embed above code in your application and run .

Shishupal Shakya
  • 1,632
  • 2
  • 18
  • 41
  • am able to convert string to spannable in my List yet they are not responding to click or touch in the Log – phpdroid Sep 03 '16 at 10:56
  • http://stackoverflow.com/questions/39313679/spannable-string-not-clickable-in-a-custom-listview – phpdroid Sep 04 '16 at 04:59
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

Nishant Desai
  • 1,492
  • 3
  • 12
  • 19