Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
fix: fix issue #24, #22, #17
  • Loading branch information
deskid committed Nov 29, 2017
commit 2c681b6516352223f0e280e9ea001cde371a3bbb
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package com.borjabravo.readmoretextviewsample;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

Expand All @@ -18,5 +25,47 @@ protected void onCreate(Bundle savedInstanceState) {
text3.setText(getString(R.string.lorem_ipsum3));
TextView text4 = findViewById(R.id.text4);
text4.setText(getString(R.string.one_line_text));
RecyclerView listView = (RecyclerView) findViewById(R.id.list);
listView.setLayoutManager(new LinearLayoutManager(this));
listView.setAdapter(new ItemAdapter());
}

static class ItemAdapter extends RecyclerView.Adapter<ViewHolder> {

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
final Context context = holder.itemView.getContext();
holder.text.setText(context.getString(R.string.lorem_ipsum));
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "you clicked " + position, Toast.LENGTH_SHORT).show();
}
});

//todo ReadMoreTextView should have a pulbic method to reset textView's collapse status
// e.g.
//((ReadMoreTextView) holder.itemView).setCollapsed(position % 2 == 0)
}

@Override
public int getItemCount() {
return 10;
}
}

static class ViewHolder extends RecyclerView.ViewHolder {
TextView text;

public ViewHolder(View itemView) {
super(itemView);
text = (TextView) itemView.findViewById(R.id.text);
}
}
}
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/round_btn_bg.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/transparent" />
<corners android:radius="6px" />
<stroke
android:width="2px"
android:color="#66666666" />
</shape>
6 changes: 6 additions & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,10 @@
android:layout_height="wrap_content"
/>

<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />


</LinearLayout>
16 changes: 16 additions & 0 deletions app/src/main/res/layout/list_item.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:background="@drawable/round_btn_bg"
android:orientation="vertical">

<com.borjabravo.readmoretextview.ReadMoreTextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:trimCollapsedText="@string/show_all_content"
app:trimLines="5" />
</LinearLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Build;
import android.support.v4.content.ContextCompat;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.TextView;
Expand Down Expand Up @@ -76,13 +78,56 @@ public ReadMoreTextView(Context context, AttributeSet attrs) {
this.trimMode = typedArray.getInt(R.styleable.ReadMoreTextView_trimMode, TRIM_MODE_LINES);
typedArray.recycle();
viewMoreSpan = new ReadMoreClickableSpan();
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
TextView widget = (TextView) v;
Spannable buffer = Spannable.Factory.getInstance().newSpannable(widget.getText());
int action = event.getAction();

// https://stackoverflow.com/questions/8558732/listview-textview-with-linkmovementmethod-makes-list-item-unclickable

// to fix a bug when call setMovementMethod will make list item unclickable
if (action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();

x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();

x += widget.getScrollX();
y += widget.getScrollY();

Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);

ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);

if (link.length != 0) {
if (action == MotionEvent.ACTION_UP) {
link[0].onClick(widget);
} else if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
}

return true;
} else {
Selection.removeSelection(buffer);
}
}
return false;
}
});
onGlobalLayoutLineEndIndex();
setText();
}

private void setText() {
super.setText(getDisplayableText(), bufferType);
setMovementMethod(LinkMovementMethod.getInstance());
setHighlightColor(Color.TRANSPARENT);
}

Expand Down Expand Up @@ -125,7 +170,15 @@ private CharSequence updateCollapsedText() {
int trimEndIndex = text.length();
switch (trimMode) {
case TRIM_MODE_LINES:
trimEndIndex = lineEndIndex - (ELLIPSIZE.length() + trimCollapsedText.length() + 1);
trimEndIndex = lineEndIndex;
//find enough space to layout ELLIPSIZE
float ellipsizeWidth = getPaint().measureText(ELLIPSIZE + trimCollapsedText);
float collapsedWidth = getPaint().measureText(text.subSequence(trimEndIndex, trimEndIndex + 1).toString());
while (collapsedWidth < ellipsizeWidth) {
--trimEndIndex;
collapsedWidth += getPaint().measureText(text.subSequence(trimEndIndex, trimEndIndex + 1).toString());
}

if (trimEndIndex < 0) {
trimEndIndex = trimLength + 1;
}
Expand Down Expand Up @@ -193,28 +246,31 @@ public void updateDrawState(TextPaint ds) {

private void onGlobalLayoutLineEndIndex() {
if (trimMode == TRIM_MODE_LINES) {
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public void onGlobalLayout() {
public boolean onPreDraw() {
ViewTreeObserver obs = getViewTreeObserver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
obs.removeOnPreDrawListener(this);
refreshLineEndIndex();
setText();
return true;
}
});
}
}

@Override
public boolean performLongClick() {
//a side affect that every slide move will trigger a long click event
return false;
}

private void refreshLineEndIndex() {
try {
if (trimLines == 0) {
lineEndIndex = getLayout().getLineEnd(0);
lineEndIndex = getLayout().getLineVisibleEnd(0);
} else if (trimLines > 0 && getLineCount() >= trimLines) {
lineEndIndex = getLayout().getLineEnd(trimLines - 1);
lineEndIndex = getLayout().getLineVisibleEnd(trimLines - 1);
} else {
lineEndIndex = INVALID_END_INDEX;
}
Expand Down