diff --git a/app/src/main/java/com/devs/readmoreoptiondemo/MyAdapter.java b/app/src/main/java/com/devs/readmoreoptiondemo/MyAdapter.java index c0d1698..aa63769 100644 --- a/app/src/main/java/com/devs/readmoreoptiondemo/MyAdapter.java +++ b/app/src/main/java/com/devs/readmoreoptiondemo/MyAdapter.java @@ -46,7 +46,7 @@ static class ViewHolder extends RecyclerView.ViewHolder { MyAdapter(Context context) { this.context = context; - readMoreOption = new ReadMoreOption.Builder(context) + readMoreOption = new ReadMoreOption.Builder(context).textLength(3,ReadMoreOption.TYPE_LINE) .build(); } @@ -62,10 +62,13 @@ public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, @Override public void onBindViewHolder(ViewHolder holder, int position) { - if (position % 2 == 0) { - readMoreOption.addReadMoreTo(holder.mTextView, Html.fromHtml(context.getString(R.string.dummy_text))); - } else { - readMoreOption.addReadMoreTo(holder.mTextView, Html.fromHtml(context.getString(R.string.dummy_text)).toString()); + if (position % 3 == 0) { + readMoreOption.addReadMoreTo(holder.mTextView, Html.fromHtml(context.getString(R.string.dummy_html_text))); + } else if (position % 2 == 0) { + readMoreOption.addReadMoreTo(holder.mTextView, Html.fromHtml(context.getString(R.string.dummy_html_text_with_new_line)).toString()); + }else{ + + readMoreOption.addReadMoreTo(holder.mTextView, context.getString(R.string.dummy_normal_text_with_new_line)); } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 712b22d..4a7d225 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -15,5 +15,9 @@ ReadMoreOption - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.]]> +

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.]]>
+ Lorem Ipsum


is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.]]>
+ \n\n\nLorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + +
diff --git a/readmoreoption/src/main/java/com/devs/readmoreoption/ReadMoreOption.java b/readmoreoption/src/main/java/com/devs/readmoreoption/ReadMoreOption.java index 7828904..a2960e7 100644 --- a/readmoreoption/src/main/java/com/devs/readmoreoption/ReadMoreOption.java +++ b/readmoreoption/src/main/java/com/devs/readmoreoption/ReadMoreOption.java @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.devs.readmoreoption; import android.animation.LayoutTransition; @@ -20,14 +19,12 @@ import android.graphics.Color; import android.os.Build; import android.os.Handler; -import android.text.Spannable; import android.text.SpannableString; 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.Log; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; @@ -36,11 +33,9 @@ * Created by ${Deven} on 6/1/18. */ public class ReadMoreOption { - - private static final String TAG = ReadMoreOption.class.getSimpleName(); public static final int TYPE_LINE = 1; public static final int TYPE_CHARACTER = 2; - + private static final String TAG = ReadMoreOption.class.getSimpleName(); // required private Context context; // optional @@ -53,7 +48,7 @@ public class ReadMoreOption { private boolean labelUnderLine; private boolean expandAnimation; - private ReadMoreOption(Builder builder){ + private ReadMoreOption(Builder builder) { this.context = builder.context; this.textLength = builder.textLength; this.textLengthType = builder.textLengthType; @@ -65,50 +60,62 @@ private ReadMoreOption(Builder builder){ this.expandAnimation = builder.expandAnimation; } - public void addReadMoreTo(final TextView textView, final CharSequence text){ - if(textLengthType==TYPE_CHARACTER) { + public void addReadMoreTo(final TextView textView, final CharSequence text) { + if (textLengthType == TYPE_CHARACTER) { if (text.length() <= textLength) { textView.setText(text); return; } - } - else { + } else { // If TYPE_LINE textView.setLines(textLength); textView.setText(text); } - textView.post(new Runnable() { @Override public void run() { - int textLengthNew = textLength; - - if(textLengthType==TYPE_LINE) { - - + SpannableStringBuilder spannableStringBuilder; + if (textLengthType == TYPE_LINE) { if (textView.getLayout().getLineCount() <= textLength) { textView.setText(text); return; } - ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) textView.getLayoutParams(); - - String subString = text.toString().substring(textView.getLayout().getLineStart(0), - textView.getLayout().getLineEnd(textLength - 1)); - textLengthNew = subString.length() - (moreLabel.length()+4+(lp.rightMargin/6)); + //get start index for last line + final int startIndex = textView.getLayout().getLineStart(textLength - 1); + //get end index for last line + final int endIndex = textView.getLayout().getLineEnd(textLength - 1); + //check char count for last line + final int charCount = endIndex - startIndex; + //more label length + int moreLabelLength = (moreLabel.length() + 4 + lp.rightMargin / 6); + //check if char count is greater than or equals more label length. + if (charCount >= moreLabelLength) { + //get substring for no of max lines and append more label + CharSequence subString = text.subSequence(textView.getLayout().getLineStart(0), + textView.getLayout().getLineEnd(textLength - 1)); + textLengthNew = subString.length() - (moreLabel.length() + 4 + lp.rightMargin / 6); + } else { + //get substring for ( no of max lines - 1) + CharSequence subString = text.subSequence(textView.getLayout().getLineStart(0), + textView.getLayout().getLineStart(textLength - 1)); + textLengthNew = subString.length(); + } } - SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text.subSequence(0, textLengthNew)) + + //get subsequence for given length and append label + spannableStringBuilder = new SpannableStringBuilder(text.subSequence(0, textLengthNew)) .append("...") .append(moreLabel); - SpannableString ss = SpannableString.valueOf(spannableStringBuilder); ClickableSpan clickableSpan = new ClickableSpan() { @Override public void onClick(View view) { addReadLess(textView, text); } + @Override public void updateDrawState(TextPaint ds) { super.updateDrawState(ds); @@ -116,14 +123,12 @@ public void updateDrawState(TextPaint ds) { ds.setColor(moreLabelColor); } }; - ss.setSpan(clickableSpan, ss.length() - moreLabel.length(), ss.length() , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - + ss.setSpan(clickableSpan, ss.length() - moreLabel.length(), ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && expandAnimation) { LayoutTransition layoutTransition = new LayoutTransition(); layoutTransition.enableTransitionType(LayoutTransition.CHANGING); - ((ViewGroup)textView.getParent()).setLayoutTransition(layoutTransition); + ((ViewGroup) textView.getParent()).setLayoutTransition(layoutTransition); } - textView.setText(ss); textView.setMovementMethod(LinkMovementMethod.getInstance()); } @@ -132,12 +137,9 @@ public void updateDrawState(TextPaint ds) { private void addReadLess(final TextView textView, final CharSequence text) { textView.setMaxLines(Integer.MAX_VALUE); - SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text) .append(lessLabel); - SpannableString ss = SpannableString.valueOf(spannableStringBuilder); - ClickableSpan clickableSpan = new ClickableSpan() { @Override public void onClick(View view) { @@ -148,6 +150,7 @@ public void run() { } }); } + @Override public void updateDrawState(TextPaint ds) { super.updateDrawState(ds); @@ -155,7 +158,7 @@ public void updateDrawState(TextPaint ds) { ds.setColor(lessLabelColor); } }; - ss.setSpan(clickableSpan, ss.length() - lessLabel.length(), ss.length() , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + ss.setSpan(clickableSpan, ss.length() - lessLabel.length(), ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(ss); textView.setMovementMethod(LinkMovementMethod.getInstance()); } @@ -169,48 +172,48 @@ public static class Builder { private String moreLabel = "read more"; private String lessLabel = "read less"; private int moreLabelColor = Color.parseColor("#ff00ff"); - private int lessLabelColor = Color.parseColor("#ff00ff"); + private int lessLabelColor = Color.parseColor("#ff00ff"); private boolean labelUnderLine = false; private boolean expandAnimation = false; - public Builder(Context context){ + public Builder(Context context) { this.context = context; } /** - * @param length can be no. of line OR no. of characters - default is 100 character + * @param length can be no. of line OR no. of characters - default is 100 character * @param textLengthType ReadMoreOption.TYPE_LINE for no. of line OR * ReadMoreOption.TYPE_CHARACTER for no. of character * - default is ReadMoreOption.TYPE_CHARACTER * @return Builder obj */ - public Builder textLength(int length, int textLengthType){ + public Builder textLength(int length, int textLengthType) { this.textLength = length; this.textLengthType = textLengthType; return this; } - public Builder moreLabel(String moreLabel){ + public Builder moreLabel(String moreLabel) { this.moreLabel = moreLabel; return this; } - public Builder lessLabel(String lessLabel){ + public Builder lessLabel(String lessLabel) { this.lessLabel = lessLabel; return this; } - public Builder moreLabelColor(int moreLabelColor){ + public Builder moreLabelColor(int moreLabelColor) { this.moreLabelColor = moreLabelColor; return this; } - public Builder lessLabelColor(int lessLabelColor){ + public Builder lessLabelColor(int lessLabelColor) { this.lessLabelColor = lessLabelColor; return this; } - public Builder labelUnderLine(boolean labelUnderLine){ + public Builder labelUnderLine(boolean labelUnderLine) { this.labelUnderLine = labelUnderLine; return this; } @@ -220,15 +223,13 @@ public Builder labelUnderLine(boolean labelUnderLine){ * - default is false * @return Builder obj */ - public Builder expandAnimation(boolean expandAnimation){ + public Builder expandAnimation(boolean expandAnimation) { this.expandAnimation = expandAnimation; return this; } - public ReadMoreOption build(){ + public ReadMoreOption build() { return new ReadMoreOption(this); } - } - }