linkify を使用して、テキストビューでリンクをクリックできるようにしています。ただし、テキストの長さが大きいと、スクロール時にテキストがちらついたり、消えたりすることがあります。テキスト ビューは、recyclerview のヘッダーの一部です。アクティビティ クラス、その xml、およびアダプターから関連するコードを投稿します。
アクティビティ:
public class NewDiscussionDetailActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_discussion_detail);
Toolbar toolbar = (Toolbar) findViewById(R.id.detail_toolbar);
aQuery = new AQuery(this);
setSupportActionBar(toolbar);
final ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setDisplayHomeAsUpEnabled(true);
ab.setTitle("Discussion");
}
Intent activityIntent = getIntent();
discussion_id = Integer.parseInt(activityIntent.getStringExtra("discussion_id"));
discussion_title = activityIntent.getStringExtra("discussion_title");
discussion_text = activityIntent.getStringExtra("discussion_text");
discussion_image_url = activityIntent.getStringExtra("discussion_image_url");
comment_count = Integer.parseInt(activityIntent.getStringExtra("discussion_comment_no"));
community_id = activityIntent.getStringExtra("community_id");
community_name = activityIntent.getStringExtra("community_name");
is_from_notification = activityIntent.getBooleanExtra("is_notification", false);
// initializing header and footer for List view
footer = getLayoutInflater().inflate(R.layout.main_list_footer, null);
header = getLayoutInflater().inflate(R.layout.discussion_detail_header, null);
prepareHeader(header);
recyclerView = (RecyclerView) findViewById(R.id.comment_list);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(recyclerView.getContext());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mLayoutManager.canScrollVertically();
recyclerView.setLayoutManager(mLayoutManager);
adapter = new CommentAdapter(commentList, this);
/* download page 1*/
adapter.addHeader(header);
recyclerView.setAdapter(adapter);
getCommentList();
/* Scroll Listener which takes care of all triggers to download to load data to adapter based position of the view*/
// code for downloading more pages of comments
}
private void prepareHeader(View header) {
/* preparing the header*/
discussion_image = (ImageView) header.findViewById(R.id.discussion_image_1);
title = (TextView) header.findViewById(R.id.discussion_title);
commentno = (TextView) header.findViewById(R.id.comment_count);
description = (TextView) header.findViewById(R.id.discussion_text_content);
title.setText(discussion_title);
title.setTypeface(AppConstants.getTypeFaceBold(this));
description.setText(discussion_text);
discriptionText = discussion_text + "";
Linkify.addLinks(description, Linkify.WEB_URLS);
description.setTypeface(AppConstants.getTypeFaceNormal(this));
if (comment_count > 2) {
commentno.setText(String.valueOf(comment_count - 1) + " comments");
} else if (comment_count == 2){
commentno.setText(String.valueOf(comment_count - 1) + " comment");
}else {
commentno.setText("Be the first to comment");
}
if (discussion_image_url == null || discussion_image_url.equals("")) {
discussion_image.setVisibility(View.GONE);
//progressbar.setVisibility(View.GONE);
} else {
discussion_image.setVisibility(View.VISIBLE);
final String image_url = discussion_image_url;
if(UtilMethod.isStringNullOrBlank(image_url))
{
//progressbar.setVisibility(View.GONE);
}
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width=dm.widthPixels;
int height=dm.heightPixels;
Picasso.with(this)
.load(image_url)
.placeholder(R.drawable.default_img_big).error(R.drawable.default_img_big)
.transform(new ImageTransformation(width))
.into(discussion_image, new Callback() {
@Override
public void onSuccess() {
// TODO Auto-generated method stub
//progressbar.setVisibility(View.GONE);
}
@Override
public void onError() {
// TODO Auto-generated method stub
//progressbar.setVisibility(View.GONE);
}
});
discussion_image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// code
}
});
}
}
アダプター:
public class CommentAdapter extends RecyclerView.Adapter<CommentAdapter.CustomViewHolder> {
ArrayList<CommentListBean> mArrayList;
Context mContext;
String event = "";
public static final int TYPE_HEADER = 111;
public static final int TYPE_FOOTER = 222;
public static final int TYPE_ITEM = 333;
//headers
List<View> headers = new ArrayList<>();
//footers
List<View> footers = new ArrayList<>();
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class CustomViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
private View view;
final TextView timestamp_tv;
final TextView chat_username;
final TextView description_tv;
final ImageView author_image_view;
final ImageView comment_image;
public CustomViewHolder(View v) {
super(v);
view = v;
chat_username = (TextView) v.findViewById(R.id.comment_author_chatname);
timestamp_tv = (TextView) v.findViewById(R.id.comment_timestamp);
description_tv = (TextView) v.findViewById(R.id.comment_text);
comment_image = (ImageView) v.findViewById(R.id.comment_image);
author_image_view = (ImageView) v.findViewById(R.id.comment_author_image);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public CommentAdapter(ArrayList<CommentListBean> arrayList, Context context) {
this.mContext = context;
this.mArrayList = arrayList;
}
// Create new views (invoked by the layout manager)
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
if (viewType == TYPE_ITEM) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.comment_list_item, null);
CustomViewHolder viewHolder = new CustomViewHolder(view);
return viewHolder;
} else {
//create a new framelayout, or inflate from a resource
FrameLayout frameLayout = new FrameLayout(parent.getContext());
//make sure it fills the space
frameLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
return new HeaderFooterViewHolder(frameLayout);
}
}
// Replace the contents of a view (invoked by the layout manager)
public void onBindViewHolder(final CustomViewHolder holder, final int position) {
//check what type of view our position is
if(position < headers.size()){
View v = headers.get(position);
//add our view to a header view and display it
prepareHeaderFooter((HeaderFooterViewHolder) holder, v);
}else if(position >= headers.size() + mArrayList.size()){
View v = footers.get(position-mArrayList.size()-headers.size());
//add oru view to a footer view and display it
prepareHeaderFooter((HeaderFooterViewHolder) holder, v);
}else {
// - code for normal comment view
}
}
@Override
public int getItemViewType(int position) {
//check what type our position is, based on the assumption that the order is headers > items > footers
if(position < headers.size()){
return TYPE_HEADER;
}else if(position >= headers.size() + mArrayList.size()){
return TYPE_FOOTER;
}
return TYPE_ITEM;
}
private void prepareHeaderFooter(HeaderFooterViewHolder vh, View view){
//empty out our FrameLayout and replace with our header/footer
vh.base.removeAllViews();
vh.base.addView(view);
}
//add a header to the adapter
public void addHeader(View header){
if(!headers.contains(header)){
headers.add(header);
//animate
notifyItemInserted(headers.size()-1);
}
}
//remove a header from the adapter
public void removeHeader(View header){
if(headers.contains(header)){
//animate
notifyItemRemoved(headers.indexOf(header));
headers.remove(header);
}
}
//add a footer to the adapter
public void addFooter(View footer){
if (!footers.contains(footer)){
footers.add(footer);
//animate
notifyItemInserted(headers.size()+mArrayList.size()+footers.size()-1);
}
}
//remove a footer from the adapter
public void removeFooter(View footer){
if(footers.contains(footer)) {
//animate
notifyItemRemoved(headers.size()+mArrayList.size()+footers.indexOf(footer));
footers.remove(footer);
}
}
//our header/footer RecyclerView.ViewHolder is just a FrameLayout
public static class HeaderFooterViewHolder extends CustomViewHolder{
FrameLayout base;
public HeaderFooterViewHolder(View itemView) {
super(itemView);
this.base = (FrameLayout) itemView;
}
}
}
ヘッダー ビューの XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_10">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/message_list_image_layout"
android:orientation="horizontal"
android:paddingTop="20dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="Representative image for the discussion"
android:background="@color/background_color"
android:id="@+id/discussion_image_1"
android:layout_marginBottom="@dimen/margin_5"
android:layout_marginTop="@dimen/margin_5"
android:src="@drawable/bg"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:maxHeight="280dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/discussion_title"
android:text="This is heading of the content"
android:layout_marginLeft="@dimen/margin_20"
android:layout_marginRight="@dimen/margin_20"
style="@style/Base.TextAppearance.AppCompat.Display1"
android:alpha="075" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/discussion_text_content"
android:layout_marginTop="@dimen/margin_10"
android:layout_marginLeft="@dimen/margin_20"
android:layout_marginRight="@dimen/margin_20"
android:text="this is the text of content. this is the text of content. this is the text of content. this is the text of content. this is the text of content.this is the text of content. this is the text of content. this is the text of content. this is the text of content. this is the text of content."
style="@style/Base.TextAppearance.AppCompat.Body1"
android:alpha="0.75" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="@dimen/margin_10"
android:layout_marginLeft="@dimen/margin_20"
android:layout_marginRight="@dimen/margin_20"
android:background="@color/dark_background_color"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="@dimen/margin_10"
android:layout_marginBottom="@dimen/margin_10"
android:layout_marginRight="@dimen/margin_20"
android:layout_marginLeft="@dimen/margin_20"
android:gravity="center_vertical|right|end"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/comment_count"
android:text="4 comments" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
スクリーンショット
LinkMovementMethod と何か関係があるような気がします。助けてください。