Using ViewTreeObserver i am adding setMaxLines and setEllipsize in MaterialTextView inside RecyclerView.Adapter

637 views Asked by At
  • I am set MaterialTextView inside RelativeLayout and set RelativeLayout size programmatically different size for every device.

  • Then i have using ViewTreeObserver to set setMaxLines and setEllipsize in MaterialTextView but i am facing some problem show the text in MaterialTextView using RecyclerView.Adapter.

  • I am using load more RecyclerView i am getting all data then after show text automatically in list and also notify data adapter then show text.

  • not showing text inside MaterialTextView in list

  • phone lock on/off then showing data in MaterialTextView

set recyclerview in fragment

recyclerView = view.findViewById(R.id.recyclerView_sub_category);
recyclerView.setHasFixedSize(true);
final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);

adapter code

public class SubCategoryAdapter extends RecyclerView.Adapter {

    private final int VIEW_TYPE_LOADING = 0;
    private final int VIEW_TYPE_ITEM = 1;
    private final int VIEW_TYPE_QUOTES = 2;

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == VIEW_TYPE_ITEM) {
           other data load
        } else if (viewType == VIEW_TYPE_QUOTES) {
            View v = LayoutInflater.from(activity).inflate(R.layout.quotes_adapter, parent, false);
            return new Quotes(v);
        } else if (viewType == VIEW_TYPE_LOADING) {
            progressbar load
        }
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, @SuppressLint("RecyclerView") final int position) {

        if (holder.getItemViewType() == VIEW_TYPE_ITEM) {

            final ViewHolder viewHolder = (ViewHolder) holder;

            // ------------- code -----

        } else if (holder.getItemViewType() == VIEW_TYPE_QUOTES) {

            final Quotes quotes = (Quotes) holder;

            quotes.relativeLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, columnWidth / 2));

            Typeface typeface = Typeface.createFromAsset(activity.getAssets(), "text_font/" + subCategoryLists.get(position).getQuote_font());
            quotes.textView.setTypeface(typeface);

            quotes.textView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {

                    quotes.textView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    int noOfLinesVisible = quotes.textView.getHeight() / quotes.textView.getLineHeight();

                    quotes.textView.setMaxLines(noOfLinesVisible);
                    quotes.textView.setEllipsize(TextUtils.TruncateAt.END);

                    quotes.textView.setText(subCategoryLists.get(position).getStatus_title());
                }
            });


        }
    }

    @Override
    public int getItemCount() {
        return subCategoryLists.size() + 1;
    }

    @Override
    public int getItemViewType(int position) {
        if (position != subCategoryLists.size()) {
            if (subCategoryLists.get(position).getStatus_type().equals("quote")) {
                return VIEW_TYPE_QUOTES;
            } else {
                return VIEW_TYPE_ITEM;
            }
        } else {
            return VIEW_TYPE_LOADING;
        }
    }

    public class Quotes extends RecyclerView.ViewHolder {

        private RelativeLayout relativeLayout;
        private MaterialTextView textView;

        public Quotes(@NonNull View itemView) {
            super(itemView);

            textView = itemView.findViewById(R.id.textView_quotes_adapter);
            relativeLayout = itemView.findViewById(R.id.rel_quotes_adapter);

        }
    }
}
3

There are 3 answers

2
Reaz Murshed On

I am not completely sure about the problem that you are having there. However, I think I found some problems in your code.

The first problem that I see in setting up your RecyclerView is setting the layout size fixed by the following.

recyclerView.setHasFixedSize(true);

Looks like you are changing the item layout size dynamically. Hence you need to remove the line above while setting up your RecyclerView.

The second problem that I see is, there is no textView_category in the ViewHolder for Quote. Hence the following should throw an error.

quotes.textView_category.setText(subCategoryLists.get(position).getCategory_name());
1
jwehrle On

One problem I can see is that you are calling

quotes.textView.getViewTreeObserver().removeOnGlobalLayoutListener(this);

in the first line of your listener callback no matter what. In a RecyclerView the first few times this is called the layout might still be unmeasured but you're cancelling the listener callback after the first callback. So this line fires, and if the view is still unmeasured then the next few lines are going to fail and your code will get no more opportunities to fill the view. Try checking the measuredWidth or measuredHeight of your view for something greater than 0 before cancelling future listener callbacks.

0
Kishan Viramgama On

I have using this. works perfectly

textView.setText(subCategoryLists.get(position).getStatus_title());
textView.post(new Runnable() {
    @Override
    public void run() {
        ViewGroup.LayoutParams params = textView.getLayoutParams();
        if (params == null) {
            params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        }
        final int widthSpec = View.MeasureSpec.makeMeasureSpec(textView.getWidth(), View.MeasureSpec.UNSPECIFIED);
        final int heightSpec = View.MeasureSpec.makeMeasureSpec(textView.getHeight(), View.MeasureSpec.UNSPECIFIED);
        textView.measure(widthSpec, heightSpec);
        textView.setMaxLines(heightSpec / textView.getLineHeight());
        textView.setEllipsize(TextUtils.TruncateAt.END);
    }
});