Reputation: 23883
How to implement hashtag inside TextView? What I want to do is implement linkable hashtag inside textview. Then user can click on it (hashtag) and switch to another fragment. This is my layout and fragment.
Layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainFragment" >
<TextView
android:id="@+id/txtHashtag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Iena I #love you !!!"/>
</RelativeLayout>
Fragment
package com.xxxx;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.xxxxx.R;
public class MainFragment extends Fragment{
private TextView txtHashtag;
public MainFragment() {
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View v = LayoutInflater.from(getActivity()).inflate(R.layout.activity_main_fragment,
null);
txtHashtag = (TextView) v.findViewById(R.id.txtHashtag);
return v;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
}
}
Upvotes: 9
Views: 10074
Reputation: 25312
Try below code to match TextView text that start with #:
...
txtHashtag = (TextView) v.findViewById(R.id.txtHashtag);
//Pattern to find if there's a hash tag in the message
Pattern tagMatcher = Pattern.compile("[#]+[A-Za-z0-9-_]+\\b");
String url = "https://www.google.co.in/";
//Attach Linkify to TextView
Linkify.addLinks(txtHashtag, tagMatcher, url);
...
Upvotes: 3
Reputation: 4285
You can use this simple library HashTagHelper
It has very simple usage:
mHashTagText = (TextView) findViewById(R.id.text);
mTextHashTagHelper = HashTagHelper.Creator.create(getResources().getColor(R.color.colorPrimary),
new HashTagHelper.OnHashTagClickListener() {
@Override
public void onHashTagClicked(String hashTag) {
}
});
// pass a TextView or any descendant of it (incliding EditText) here.
// Hash tags that are in the text will be hightlighed with a color passed to HasTagHelper
mTextHashTagHelper.handle(mHashTagText);
Upvotes: 15
Reputation: 1298
Use this, Clickable Span in TextView
// setting span
SpannableString tagSpan = new SpannableString("#clickMe");
ClickableSpan clickSpan = new ClickableSpan() {
@Override
public void onClick(View textView) {
//code to swtich to new fragment
}
@Override
public void updateDrawState(TextPaint paint) {
super.updateDrawState(paint);
paint.setUnderlineText(true); // set underline if you want to underline
paint.setColor(Color.BLUE); // set the color to blue
}
};
tagSpan.setSpan(clickSpan, startPosition, endPosition, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
TextView txtHashtag = (TextView) findViewById(R.id.txtHashtag);
txtHashtag.setText(tagSpan);
txtHashtag.setMovementMethod(LinkMovementMethod.getInstance());
You can implement more than one span in a textView, so simply write a function to do that and call it for each #HashTag
Upvotes: 3
Reputation: 15
Whatever view you want it to be reacting with clicks, you have to attach an onClickListener to it just like you implemented on button (assuming you have understood mechanics of button clicks).
therefore, it is possible to have it like this:
txtHashtag.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// This is where you call the method to change fragment
}
});
As for the method to go to the said fragment, ensure you have that fragment configured to receive parameters during instantiation as such:
public class HashtagViewFragment extends Fragment {
private static final String TAG = "HashtagViewFragment";
public static final String PARAM_HASHTAG = "hashtag_string";
private TextView txtPassedString;
private String receivedString;
public static HashtagViewFragment newInstance(String myHashtag) {
HashtagViewFragment fragment = new HashtagViewFragment();
Bundle args = new Bundle();
args.putString(PARAM_HASHTAG, myHashtag);
fragment.setArguments(args);
return fragment;
}
public HashtagViewFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
receivedString = getArguments().getString(PARAM_HASHTAG);
} else {
receivedString = "";
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.HashtagViewFragment, container, false);
txtPassedString = (TextView) view.findById(R.id.tv_hashtag);
txtPassedString.setText(receivedString);
return view;
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
@Override
public void onDetach() {
super.onDetach();
}
}
then, your ViewPager adapter needs to be configured as such that it can instantiate the fragments on demand like so:
public class HashtagPagerAdapter extends FragmentStatePagerAdapter {
private Context mContext;
private ArrayList<String> hashtags = new ArrayList<>();
public HashtagPagerAdapter(FragmentManager fm, Context ctx) {
super(fm);
this.mContext = ctx;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new MainFragment();
default:
return HashtagViewFragment.newInstance(hashtags.get(position - 1));
}
}
private void setHashtags(ArrayList<String> latestHashtags) {
this.hashtags = latestHashtags;
notifyDataSetChanged();
}
private ArrayList<String> getHashtags() {
return this.hashtags;
}
@Override
public int getCount() {
return hashtags.size() + 1;
}
}
Provided the ViewPager is public static in your FragmentActivity object, you can access it from your MainFragment like this:
MyFragmentActivity.myViewPager
With this in mind, you may now create the method to add and swap fragment as follows:
private void swapFragment() {
ArrayList<String> currentHashtags = ((HashtagPagerAdapter)MyFragmentActivity.myViewPager.getAdapter()).getHashtags();
currentHashtags.add(txtHashtag.getText().toString());
((HashtagPagerAdapter)MyFragmentActivity.myViewPager.getAdapter()).setHashtags(currentHashtags);
MyFragmentActivity.myViewPager.setCurrentItem(currentHashtags.size(), true);
}
Upvotes: 0