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

 

번호 제목 글쓴이 날짜 조회 수
68 TTS 를 위한 스마트폰 설정 및 TTS 샘플 file 황제낙엽 2019.02.16 460
67 Creating swipe views with tabs file 황제낙엽 2019.02.10 102
66 [번역] 안드로이드 ViewPager 를 이용한 수평 화면 전환 file 황제낙엽 2019.02.09 71
» 동적 레이아웃 생성과 자동 줄바꿈 구현 file 황제낙엽 2018.12.26 311
64 qemu-system-~.exe 의 작동이 중지되었습니다 file 황제낙엽 2018.11.27 55
63 Configuration 'compile' is obsolete and has been replaced with 'implementation' and 'api'. file 황제낙엽 2018.11.27 59
62 Error:Minimum supported Gradle version is 4.1. 황제낙엽 2018.11.27 84
61 No toolchains found in the NDK toolchains folder for ABI 황제낙엽 2018.11.27 33
60 [성공샘플] HttpURLConnection 을 이용하여 JSON 데이터 보내기 예제 황제낙엽 2018.11.10 649
59 [Android] 네이버 음성합성(TTS) API 사용해 보기 file 황제낙엽 2018.11.01 167
58 [Android] TTS (Text To Speech) API 샘플 코드 file 황제낙엽 2018.11.01 128
57 Google Cloud API 설정법 file 황제낙엽 2018.11.01 39
56 AsyncTask 사용하기 황제낙엽 2018.10.29 36
55 Volley 소개 및 관련 링크 황제낙엽 2018.10.29 63
54 AsyncTask 를 이용한 HttpURLConnection 사용법 [1] 황제낙엽 2018.10.20 33
53 HttpURLConnection 을 이용하여 JSON 데이터 보내기 예제 [1] file 황제낙엽 2018.10.20 102
52 STT 학습 링크 모음 (sample link) 황제낙엽 2018.10.11 552
51 코틀린(Kotlin) 학습용 링크 모음 황제낙엽 2018.10.11 64
50 저장소 파일 불러올 때 권한 요청 설정 file 황제낙엽 2018.08.21 55
49 안드로이드 파일시스템에 파일 생성하여 데이터 저장, 불러오기 예제 황제낙엽 2018.08.21 58