01/06 78-1 [Android] Costomview
뷰를 커스텀하기
java > view > CustomView.java
이거 어디있나 한 참 찾았다..
//1.view 클래스 상속
public class CustomView extends View {
//2.Context를 매개변수로 받은 생성자[자바코드용]
public CustomView(Context context) {
super(context);
Log.i("com.kosmo.customview","뷰 객체로 화면 표시");
}
//2-1.context와 AttributeSet를 매개변수로 받는 생성자[xml용]
public CustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
Log.i("com.kosmo.customview","xml로 화면 표시");
}
//3.onDraw()메소드 오버라이딩(마우슨 우클릭 Generate - 오버라이딩! )
@Override
protected void onDraw(Canvas canvas) {
//배경색 설정
canvas.drawColor(Color.CYAN);
//붓 생성
Paint paint = new Paint();
paint.setAntiAlias(true); //붓을 부드럽게 설정
//붓 색상 설정
paint.setColor(Color.RED);
paint.setStrokeWidth(30); //단위는 픽셀, 붓 두깨
//점 그리기
canvas.drawPoint(100,100,paint);
//선 그리기
paint.setStrokeWidth(10);
canvas.drawLine(150,150,500,150,paint);
//사각형
paint.setColor(0x88911740);
canvas.drawRect(150,150,500,350,paint);
//원그리기
paint.setColor(Color.argb(255,0,255,0));
canvas.drawCircle(250,450,100,paint);
//이미지 그리기
/*
paint는 null 지정 그래야 이미지 원래 색대로 그려짐!
원본크기 그대로 출력
1.drawBitma(bitmap객체,x,y,pain객체)
*/
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_lock_airplane_mode_alpha);
// canvas.drawBitmap(bitmap,250,550,null);
//2..drawBitma(bitmap객체,null,rect dest,Pain객체-null)
//null지정시 원본이미지 전체가 선택된 후 확대 축소 가능
// canvas.drawBitmap(bitmap,null,new Rect(250,550,250+400,550+400),null);
//3.drawBitmap(Bitmap객체,Rect src,Rect dest,Paint객체)
//원본의 특정 부분 선택후 확대 축소
canvas.drawBitmap(bitmap,new Rect(0,0,100,100),new Rect(250,550,250+400,550+400),null);
}
stroke은 보더역할
기본 제공 이미지는 저기 저 경로로 가면 있음
activity_main.xml
<!--내가만든 뷰를 xml로 전개 시 -->
<com.kosmo.customview10_1.view.CustomView
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.kosmo.customview10_1.view.CustomView>
태마도
AndroidManifest.xml
android:theme="@style/Theme.CustomView10_1"
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//레이아웃 xml파일로 뷰 전개
//setContentView(R.layout으로 시작하는리소스 아이디)
setContentView(R.layout.activity_main);
//내가만든 뷰로 전개
// setContentView(new CustomView(this));
}
}
자바코드로 버튼 제어하기
https://developer.android.com/topic/libraries/view-binding?hl=ko#java
findViewById대신 뷰 결합 사용(쟤는 같은 아이디 사용 시 충돌이 일어날 수 있는 문제가 있음)
뷰 바인딩 활성화 해야 함(설정파일에 설정 )
Gradle Scripts > buil.gradle(Mocule: ) 폴더 에
android{ } 요 안에!!
viewBinding {
enabled = true
}
넣고 sync now 눌러준다
앱 한 번 실행하고
좌측 상단 Android 를 Project탭으로 변경 후
app->build->generated->data_binding_~밑에 바인딩 클래스가 생성됨을 확인
ActivityMainBinding(그림참고)
그 뒤로는 기억이 잘 안나서 순서가 뒤죽박죽임..... 나중에 시간있으면
그때 순서 맞춰놔야겠다...
activity_main.xml
<EditText
android:hint="메시지를 입력하세요!"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/infoMessage"
android:textSize="20sp"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<Button
android:id="@+id/btnShort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="짧은 메시지"
/>
<Button
android:id="@+id/btnLong"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="긴 메시지"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp"
/>
<Button
android:id="@+id/btnCustom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="커스텀뷰" />
</LinearLayout>
MainActivity.java
rootView는 무조건 있음! 루트 뷰는 최상위 뷰(레이아웃)를 의미함!!
inflate() 가 setContentView 와 같음(전개하는 역할)
private ActivityMainBinding binding;
private ToastLayoutBinding toastLayoutBinding;
private View toastRootView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
//activity_main.xml을 추상화한 클래스 얻기
binding= ActivityMainBinding.inflate(getLayoutInflater());
toastLayoutBinding = toastLayoutBinding.inflate(getLayoutInflater());
//최상위 레이아웃(루트 뷰 ! 여기선 LinearLayout 요거 통째로 가져오는 것)을 얻기
View rootview = binding.getRoot();
toastRootView=toastLayoutBinding.getRoot();
//레이아웃 전개
setContentView(rootview);
//binding객체로 뷰에 직접 접근
//리스너 부착
binding.btnShort.setOnClickListener(handler);
binding.btnLong.setOnClickListener(handler);
binding.btnCustom.setOnClickListener(handler);
}////
//이벤트 처리하기(익명클래스로)
private View.OnClickListener handler = view ->{
String msg = binding.infoMessage.getText().toString();
if(view.getId()==R.id.btnShort){
Toast.makeText(view.getContext(), msg, Toast.LENGTH_SHORT).show();
}
else if(view.getId()==R.id.btnLong){
Toast.makeText(view.getContext(), msg, Toast.LENGTH_LONG).show();
}
else{
//사용자 입력값을 토스트용 커스텀뷰의 덱스트뷰에설정
toastLayoutBinding.textView.setText(msg);
Toast toast = new Toast(view.getContext());
//토스트 지속시간설정
toast.setDuration(Toast.LENGTH_LONG);
//토스트의 화면전개
toast.setView(toastRootView);
//토스트보이기!!!
toast.show();
}
};
토스트용 커스텀 뷰 설정
toast_layout.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:padding="10dp"
android:background="@drawable/layout_rounded"
>
<ImageView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="50dp"
android:src="@drawable/icon2"
android:scaleType="fitXY"
/>
<TextView
android:layout_width="0dp"
android:layout_weight="8"
android:layout_height="50dp"
android:id="@+id/textView"
android:gravity="center"
android:textColor="@color/white"
android:textSize="18sp"
android:maxLines="1"
android:ellipsize="end"
/>
<!--
... 표시하기
android:singleLine="true" dprecated됨
android:maxLines="1" :한 줄만 표시
ellipsize:Text가 TextView를 넘어갔을 때 표시할 방법을 설정
ellipsize = "end" - 뒷 부분을 ...으로 표시
아래는 maxLines와 함께쓰면 빨간줄 :tools:ignore="EllipsizeMaxLines" 추가 시 제거됨
ellipsize = "none" - ... 없이 뒷 부분 잘라서 표시 (기본)
ellipsize = "start" - 앞 부분을 ...으로 표시
ellipsize = "middle" - 중간 부분을 ...으로 표시
ellipsize = "marquee" - 흐르는 텍스트 효과
아래 세줄과 자바코드에서 textView.setSelected(true)추가하면 marquee가 적용 됨
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
-->
</LinearLayout>
위젯을 배우자
activity_main.xml
버튼의 색상을 #ffffffff등 색생코드로 지정하려면
매니페스트파일의 theme속성을 Theme.AppCompat계열로
바꿔라
예:android:theme="@style/Theme.AppCompat.DayNight.DarkActionBar"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/linearlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FF00FF00"
android:text="기본 버튼"/>
<!-- android:enabled="false"시 디폴트 버튼이 표시된다-->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="셀렉터 버튼(이미지)"
android:background="@drawable/button_image_selector"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/button_color_selector"
android:text="셀렉터 버튼(색상)"/>
<!--입력한 문자열의 길이 출력을 하기위한 텍스트뷰-->
<!-- 시스템에서 제공하는 기본 에디트 텍스트-->
<TextView
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="20dp"
android:background="#8BC34A"
android:text="여기에 문자열 길이 표시" />
<EditText
android:id="@+id/basicEditText"
android:hint="기본 에디트 텍스트"
android:textColorHint="#00ff00"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!--내가 만든 커스텀 EditText-->
<!-- 아래 주석처리후 자바코드에서 직접 new로 생성-->
<com.kosmo.customview10_3.view.MyEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/myEditText"
android:hint="내가 만든 에디트 텍스트"
android:textColorHint="#FF0000"
/>
</LinearLayout>
여러 res 사용할거
drawable 폴더에 이미지 등 넣어놓기
MainActivity.java
제어하기
public class MainActivity extends AppCompatActivity {
//기본 에디트 텍스트상자로 문자열길이 표시 구현용
private int textLength;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//위젯 얻기
TextView textView = findViewById(R.id.textview);
EditText editText = findViewById(R.id.basicEditText);
LinearLayout layout = findViewById(R.id.linearlayout);
//1]내가 만든 EditText를 자바코드로 부착하는 경우
//MyEditText myEditText= new MyEditText(this);
//myEditText.setHint("내가 만든 에디트 텍스트");
//myEditText.setHintTextColor(Color.RED);
//myEditText.setOnTextLengthListener(txtLength->textView.setText(String.valueOf(txtLength)));
//레이아웃(루트 뷰)에 부착 :addView(View view)
//layout.addView(myEditText);
//2]xml에 내가 만든 EditText를 태그로 등록한 경우
MyEditText myEditText=findViewById(R.id.myEditText);
myEditText.setOnTextLengthListener(txtLength->textView.setText(String.valueOf(txtLength)));
editText.addTextChangedListener(new TextWatcher() {
//한글자 입력전 혹은 삭제전마다 호출됨
@Override
public void beforeTextChanged(CharSequence text, int start, int count, int after) {
Log.i("com.kosmo.customview","기본 에디트텍스트:[beforeTextChanged]");
}
//한글자 입력시 혹은 삭제시마다 호출됨
@Override
public void onTextChanged(CharSequence text, int start, int before, int count) {
/*
text:에디트 텍스트에 입력된 문자열
start:새로 추가되거나 삭제된 문자열의 시작 인덱스
before:삭제된 문자열의 갯수
count:새로 추가된 문자열의 갯수
*/
textLength+=count-before;
textView.setText(String.valueOf(textLength));
Log.i("com.kosmo.customview","기본 에디트텍스트:[onTextChanged]");
Log.i("com.kosmo.customview",String.format("text:%s,start:%s,before:%s,count:%s",text,start,before,count));
}
//한글자 입력후 혹은 삭제후마다 호출됨
@Override
public void afterTextChanged(Editable editable) {
Log.i("com.kosmo.customview","기본 에디트텍스트:[afterTextChanged]");
}
});
}///////////////