sitelink1 https://blog.naver.com/mapl003/221232818507 
sitelink2  
sitelink3  

샘플소스파일 -> main.zip

 

Linear Layout 밖에 없는 XML에 동적으로 TextView와 LinearLayout을 생성하여 자동 개행하는 기능을 구현해보겠습니다.

 

구현하고자 하는 기능

1. 문자열을 공백을 기준으로 String 배열에 저장합니다.

2. 저장된 String 배열의 요소를 각각 TextView에 넣습니다.

3. TextView는 다시 동적으로 생성한 Linear Layout에 추가합니다.

4. TextView 길이의 합이 부모뷰의 가로길이보다 클 경우 다음 LinearLayout에 추가합니다.

5. 생성된 LinearLayout을 뷰에 추가해줍니다.

 

<!--activity_main.xml-->

 

<?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"

    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/contents"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    android:gravity="center"

    tools:context="com.study.dynamiclayout.MainActivity">

 

 

 

</LinearLayout>

 

package com.study.dynamiclayout;

 

import android.content.Context;

import android.graphics.Color;

import android.graphics.Typeface;

import android.support.v4.widget.TextViewCompat;

import android.util.Log;

import android.view.View;

import android.view.ViewGroup;

import android.widget.LinearLayout;

import android.widget.TextView;

 

/**

 * Created by mapl0 on 2018-03-20.

 */

 

public class DynamicNewLine {

 

    public DynamicNewLine() {}

 

    public void getNewLineLayout(final String str, final int fontSize, final Context context, final ViewGroup parent) {

 

 

        //부모뷰가 초기화가 된 다음 메소드를 실행해주지 않으면 contents의 getWidth 값은 0을 반환한다.

        parent.post(new Runnable() {

            @Override

            public void run() {

                String[] strArr = str.split(" ");

 

                int space = fontSize / 2; // 폰트크기의 절반만큼을 공백으로 사용함.

                int textViewTotalWidth = 0; //TextView의 길이 합을 알기 위해 사용합니다.

                int linearCount = 0;

 

                //분할된 문자열을 저장한 TextView 동적 생성

                TextView[] textViewArr = new TextView[strArr.length];

 

                //TextView 초기화

                for (int i = 0; i < textViewArr.length; i++) {

 

                    //동적 레이아웃 생성

                    textViewArr[i] = new TextView(context);

                    textViewArr[i].setText(strArr[i]);

                    textViewArr[i].setTextSize(fontSize);

 

                    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(

                            ViewGroup.LayoutParams.WRAP_CONTENT,

                            ViewGroup.LayoutParams.WRAP_CONTENT);

 

                    textViewArr[i].setLayoutParams(params);

                    textViewArr[i].setTextColor(Color.BLACK);

                    textViewArr[i].setTypeface(Typeface.DEFAULT_BOLD);

 

                    textViewArr[i].setSingleLine();

 

                    //부모 뷰에서 onDraw 하기 전에 부모뷰에 크기를 위임하여 길이를 알아오기 위함

                    textViewArr[i].measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

                    textViewTotalWidth += textViewArr[i].getMeasuredWidth();

 

                    //마지막 TextView가 아닐 경우 공백 추가

                    if(i != textViewArr.length-1) {

                        params.setMargins(0, 0, space, 0);

                        textViewTotalWidth += space;

                    }

 

                }

 

                //TextViewTotalWidth를 이용하여 동적 생성할 Linear Layout의 개수를 알 수 있다.

                //텍스트뷰 길이의 합을 부모뷰의 가로길이로 나눈다.

                LinearLayout[] linearBox;

                if(parent.getWidth() != 0) {

 

                    //LinearLayout 초기화

                    linearBox = new LinearLayout[textViewTotalWidth / parent.getWidth() + 1];

                    for (int i = 0; i < linearBox.length; i++) {

                        linearBox[i] = new LinearLayout(context);

                        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

                        params.setMargins(0, space, 0, space);

                        linearBox[i].setLayoutParams(params);

                        linearBox[i].setOrientation(LinearLayout.HORIZONTAL);

                    }

 

                    textViewTotalWidth = 0;

 

                    for(int i=0; i<textViewArr.length; i++) {

 

                        textViewArr[i].measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

                        textViewTotalWidth += textViewArr[i].getMeasuredWidth();

 

                        //마지막 TextView가 아닐 경우 공백 추가

                        if(i != textViewArr.length-1) {

                            textViewTotalWidth += space;

                        }

 

                        //만약 가로뷰보다 추가될 텍스트뷰 가로합이 더 작다면 레이아웃에 추가해줌.

                        if(linearCount < linearBox.length && textViewTotalWidth < parent.getWidth()) {

                            linearBox[linearCount].addView(textViewArr[i]);

                        } else {

                            //그렇지 않으면 다음 레이아웃으로 넘거가고 같은 작업을 다시 실시

                            textViewTotalWidth = 0;

                            linearCount++;

                            i--; // 같은 작업을 한번 더 실시하게 함.

                        }

 

                    }

 

                    //마지막으로 부모뷰에 레이아웃을 추가해준다.

                    for(int i=0; i<linearBox.length; i++) {

                        parent.addView(linearBox[i]);

                    }

                }

 

                else Log.d("Error", "부모뷰의 getWidth를 구할 수 없습니다.");

            }

        });

 

    }

 

}

 

package com.study.dynamiclayout;

 

import android.content.Context;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.widget.LinearLayout;

 

public class MainActivity extends AppCompatActivity {

 

    private android.widget.LinearLayout contents;

    private Context context;

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

 

        this.contents = (LinearLayout) findViewById(R.id.contents);

        context = this;

 

        DynamicNewLine dynamic = new DynamicNewLine();

        dynamic.getNewLineLayout("개행이 과연 잘 될까요? 개행이 과연 잘 될까요? 개행이 과연 잘 될까요? 개행이 과연 잘 될까요? 개행이 과연 잘 될까요?", 20, context, contents);

 

 

    }

}

 

 

 

결과화면

 

image.png

 

번호 제목 글쓴이 날짜 조회 수
128 단말기 고유값 구하는 방법들 황제낙엽 2019.03.03 11739
127 뷰 캡처하여 이미지 파일로 저장하기(화면 캡처)-04 file 황제낙엽 2018.08.12 1711
126 고유 식별자의 모범 사례 (Android Developers) 황제낙엽 2019.03.03 1106
125 Emulator: audio: Failed to create voice `adc' 황제낙엽 2018.08.06 1007
124 뷰 캡처하여 이미지 파일로 저장하기(화면 캡처)-06 file 황제낙엽 2018.08.19 991
123 HTTP 프로토콜을 이용한 Json Post 보내고 받기 file 황제낙엽 2017.08.03 816
122 Error:Execution failed for task ':app:lintVitalRelease'. 황제낙엽 2018.01.29 783
121 파일 입출력(내장 메모리, 외장메모리) 황제낙엽 2018.08.19 720
120 HttpURLConnection 에서 세션 유지하기(쿠키 사용) 황제낙엽 2017.08.03 661
119 [성공샘플] HttpURLConnection 을 이용하여 JSON 데이터 보내기 예제 황제낙엽 2018.11.10 649
118 Image to byte Array (바로 사용가능한 JPEG 파일) 황제낙엽 2018.07.24 612
117 STT 학습 링크 모음 (sample link) 황제낙엽 2018.10.11 552
116 ABI 관리 황제낙엽 2017.03.28 535
115 TTS 를 위한 스마트폰 설정 및 TTS 샘플 file 황제낙엽 2019.02.16 460
114 안드로이드 스튜디오(Android Studio) 최적화 file 황제낙엽 2018.02.07 433
113 android.webkit.CookieManager 를 이용한 웹뷰와의 세션 공유 황제낙엽 2019.04.26 322
» 동적 레이아웃 생성과 자동 줄바꿈 구현 file 황제낙엽 2018.12.26 311
111 Android - Actionbar에 tab을 추가하고 스와이프 동작으로 화면 전환 구현( ViewPager와 FragmentPagerAdapter 사용) file 황제낙엽 2017.09.11 308
110 안드로이드 두지점(위도,경도) 사이의 거리 file 황제낙엽 2017.01.25 257
109 안드로이드 기기 식별 방법 - UUID(Universally unique identifier) 황제낙엽 2019.03.03 234