Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add several textViews (of variable widths) in relativeLayout one after another

I have a relative layout section. Within it, i have to programmatically add several clickable textviews that may vary in widths. I need them to appear one after another. If a textView has width such that it cannot fit in the remaining space of the current row, it should start populating below the row in a similar fashion.

I need something like this: illustration of what i want

What i've managed so far is this code below:

public static void updateWordsListingOnUi(final ArrayList<String> wordsList) { //TODO: incomplete and may be inefficient
    mUiHandler.post(new Runnable() {
        @Override
        public void run() {
            TextView textView;

            wordsListingContainer.removeAllViewsInLayout(); //TODO
            for (final String word : wordsList)
            {
                textView = new TextView(context);
                textView.setText(word);
                textView.setClickable(true);
                textView.setPadding(1,1,10,1);
                if (wordsList.indexOf(word)%2 == 0) {
                    textView.setBackgroundColor(context.getResources().getColor(R.color.colorPrimary));
                }
                else {
                    textView.setBackgroundColor(context.getResources().getColor(R.color.colorAccent));
                }
                textView.setId(wordsList.indexOf(word)); //give IDs from 0 - (maxSize-1)

                textView.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        Toast.makeText(context, word, Toast.LENGTH_SHORT).show();
                    }
                });
                if(wordsList.indexOf(word) > 0) {
                    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
                    layoutParams.addRule(RelativeLayout.RIGHT_OF, textView.getId()-1); //TODO
                    wordsListingContainer.addView(textView,layoutParams);
                }
                else {
                    wordsListingContainer.addView(textView);
                }

            }
        }
    });
}

This does the job partially. It puts textviews one after the other, but when there i insufficient space, it doesn't wrap to the next row. I cannot think of how i can do that.

like image 463
Abdul Wasae Avatar asked Jul 21 '16 09:07

Abdul Wasae


People also ask

How to add a textview to a linearlayout dynamically in Android?

How to add a TextView to a LinearLayout dynamically in Android? This example demonstrates about How to add a TextView to a LinearLayout dynamically in Android Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project.

How to create a dynamic view in Android using relativelayout?

Android RelativeLayout inside create + add view dynamically using coding activity file. Relative layout is most flexible layout available to develop android applications because this is the only view that gives us the facility to move or add view at any location on activity.

How to vertically center view in relative layout Android programmatically?

Align view to vertically center in relativelayout android programmatically. Center textview text horizontally and vertically inside TextView android. Set TextView Vertically center in android programmatically. Place a view in center of relativelayout android using xml. Move EditText layout just above soft keyboard when it shows in android.

What are the attributes of relative layout in Android?

RelativeLayout Attributes Following are the important attributes specific to RelativeLayout − Sr.No. Attribute & Description 1 android:id This is the ID which uniquely identifies the layout. 2 android:gravity This specifies how an object should position its content, on both the X and Y axes.


2 Answers

Here is a tutorial, that explains how, you can do this.

In short, your class need to be something like:

public class TagLayout extends ViewGroup {
    int deviceWidth;

    public TagLayout(Context context) {
        this(context, null, 0);
    }

    public TagLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TagLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        Point deviceDisplay = new Point();
        display.getSize(deviceDisplay);
        deviceWidth = deviceDisplay.x;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int count = getChildCount();
        int curWidth, curHeight, curLeft, curTop, maxHeight;

        //get the available size of child view
        final int childLeft = this.getPaddingLeft();
        final int childTop = this.getPaddingTop();
        final int childRight = this.getMeasuredWidth() - this.getPaddingRight();
        final int childBottom = this.getMeasuredHeight() - this.getPaddingBottom();
        final int childWidth = childRight - childLeft;
        final int childHeight = childBottom - childTop;

        maxHeight = 0;
        curLeft = childLeft;
        curTop = childTop;

        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);

            if (child.getVisibility() == GONE)
                return;

            //Get the maximum size of the child
            child.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST));
            curWidth = child.getMeasuredWidth();
            curHeight = child.getMeasuredHeight();
            //wrap is reach to the end
            if (curLeft + curWidth >= childRight) {
                curLeft = childLeft;
                curTop += maxHeight;
                maxHeight = 0;
            }
            //do the layout
            child.layout(curLeft, curTop, curLeft + curWidth, curTop + curHeight);
            //store the max height
            if (maxHeight < curHeight)
                maxHeight = curHeight;
            curLeft += curWidth;
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int count = getChildCount();
        // Measurement will ultimately be computing these values.
        int maxHeight = 0;
        int maxWidth = 0;
        int childState = 0;
        int mLeftWidth = 0;
        int rowCount = 0;

        // Iterate through all children, measuring them and computing our dimensions
        // from their size.
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);

            if (child.getVisibility() == GONE)
                continue;

            // Measure the child.
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
            maxWidth += Math.max(maxWidth, child.getMeasuredWidth());
            mLeftWidth += child.getMeasuredWidth();

            if ((mLeftWidth / deviceWidth) > rowCount) {
                maxHeight += child.getMeasuredHeight();
                rowCount++;
            } else {
                maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
            }
            childState = combineMeasuredStates(childState, child.getMeasuredState());
        }

        // Check against our minimum height and width
        maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
        maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());

        // Report our final dimensions.
        setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
                resolveSizeAndState(maxHeight, heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT));
    }
}
like image 65
Michael Spitsin Avatar answered Sep 24 '22 01:09

Michael Spitsin


Why don't you try out libraries, here i am sharing some of the links

Chips EditText Library
MultiTextTagView
TokenAutoComplete
Android Chips

These libraries will help you to achieve your output.

like image 39
Ravi Avatar answered Sep 26 '22 01:09

Ravi