117일차(2)/Android App(74) : Wearable App 예제(1)
- Android Studio 에서 새 가상기기(Wear OS) 만들기
- 디바이스 관리-새 디바이스 생성하기
- Wear OS를 선택해준다.
- Wear OS Square : 화면이 사각형인 것
- Wear OS Round : 화면이 동그란 것
- 시계 화면 모양을 기준으로 가상기기를 생성한다.
- round를 선택해줌!
- 두번째 R을 다운받아주기!
- 맨 위의 것은 China Version 이라 언어가 중국어로 나온다.
- 이렇게 Wearable device의 가상기기를 만들 수 있다.
- 가상기기 생성에 시간이 오래 걸리므로 모듈을 생성하기 전에 만들어 놓으면 좋다.
- Wear OS 도 Android와 비슷하다. 모바일 앱과 크게 다르지 않다!
- 작은 화면이라 레이아웃을 구성하는 것만 좀 다를 뿐..
- 생성이 완료되면 Finish
- 가상기기의 이름, 기본 방향 등을 정해주면 완료된다.
- 생성된 가상기기이다.
- 위=>아래로 스크롤 : 설정 정보
우측으로 스크롤 : 알림 센터
아래=>위로 스크롤 알림
좌측으로 스크롤 : 동그란 스탑워치?같은 창 나옴
- 좌측에서 나오는 창!
- 설정:연결, 디스플레이, 제스처, 진동, 보안, 시스템... 등등이 있다.
- 시계에서 뒤로가기 기능(백 버튼)을 사용하고 싶다면 보통 우측으로 드래그하면 된다.
- Wear용 새 모듈 생성
step26wear
- WearOS 시계를 선택
- wear의 액티비티 선택 창 : Blank Activity로 선택
- 시계는 주로 다른 모바일 기기와 페어링해서 쓴다.
- 가상기기 메뉴에서 페어링 관련된 옵션을 제공하고 있다.
- 실 기기로도, 다른 가상기기로도 페어링 가능!
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.wear.widget.BoxInsetLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/box_inset_layout_padding"
tools:context=".MainActivity"
tools:deviceIds="wear">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/inner_frame_layout_padding"
app:layout_boxedEdges="all"
android:orientation="vertical">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello_world"
android:textAlignment="center"
android:textColor="#00ff00"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="눌러보셈"
android:id="@+id/myBtn"/>
</LinearLayout>
</androidx.wear.widget.BoxInsetLayout>
- 제일 바깥쪽의 BoxInsetLayout 안에 FrameLayout이 들어있다.
- 기본값으로 어느정도 padding을 준 것을 확인 가능
- Wear에서는 크기에 관련된 설정값들을 xml문서로 정리해 두었다.
- 들어가보면 boxInset의 padding, frameLayout의 padding이 각각 0dp, 5dp라고 지정되어 있다.
- 사각형인 경우에는 레이아웃을 적당히 맞도록 배치해도 되는데,
- 스크린이 원형인 경우에는 위와 같이 잘리는 부분들이 생긴다. 그 부분을 감안해 padding을 준 것이다.
- 원형 안에 잘리는 내용 없이 바로 배치할 수 있도록 padding을 부여한 부분!
MainActivity
package com.example.step26wear;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import com.example.step26wear.databinding.ActivityMainBinding;
public class MainActivity extends Activity {
private TextView mTextView;
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//바인딩 객체를 얻어내고
binding = ActivityMainBinding.inflate(getLayoutInflater());
//바인딩 객체를 이용해서 화면 구성을 하고
setContentView(binding.getRoot());
//TextView의 참조값을 얻어와서 필드에 저장
mTextView = binding.text;
//버튼에 리스너 등록
binding.myBtn.setOnClickListener(v -> {
//TextView 조작하기
binding.text.setText("Clicked!");
});
}
}
- 기본적으로 뷰 바인딩을 사용한다.
- 액티비티의 두 단어를 거꾸로 조합한 바인딩 객체가 자동으로 생긴다.
- 이 기본 앱을 run해보기!
- 이렇게 기본 화면이 나타남!
- 패딩을 이렇게 사방으로 5dp씩 가지고 있다. 그래서 알아서 레이아웃 배치를 해준다.
- 레이아웃은 사각형 시계 쪽이 쉽다.
- values>strings 폴더 안에 앱 안에 들어갈 글자를 따로 배치해 놓았다.
- 이것을 프로젝트로 바꿔서 보면 프로젝트 구조를 보기가 좀 더 쉽다.
(필요한 것만 보려면 android로 보면 된다)
- src 안에서 코딩하면 된다. 똑같다!
- res 에 values 폴더가 2개 있다.
- values 폴더(디폴트)는 사각형 시계일때 사용하는 자원
values-round 는 동그란 화면일때 가져다 쓰는 자원! 폴더명 자체가 다르다.
- activity_main.xml 수정하기
- 리니어 레이아웃으로 바꿔도 똑같다. 위에서 쌓이는 구조로 바뀌었다.
- 버튼을 만들면 이렇게 출력된다.
- box inset을 쓰고 기본 padding이 들어있다는 것만 아니면 일반 안드로이드의 코딩과 별 차이가 없다.
- 버튼에 리스너 등록
- 안드로이드의 "텍스트" 가운데 정렬은 text-Alignment 사용
- 다른 요소들은 gravity를 사용
- 버튼을 클릭하면 버튼 위의 input에 Clicked! 가 표시되도록 만들어보았다.
- 새 모듈 생성
step26listview
- WearOS로 생성하기
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.wear.widget.BoxInsetLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/box_inset_layout_padding"
tools:context=".MainActivity"
tools:deviceIds="wear">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/inner_frame_layout_padding"
app:layout_boxedEdges="all">
<androidx.wear.widget.WearableRecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recyView"
android:scrollbars="vertical"/>
</FrameLayout>
</androidx.wear.widget.BoxInsetLayout>
<androidx.wear.widget.WearableRecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recyView"
android:scrollbars="vertical"/>
- FrameLayout 안에 이렇게 WearableRecyclerView 요소를 작성해주기
- 스크롤바는 수직으로!
MainActivity
package com.example.step26listview;
import android.app.Activity;
import android.os.Bundle;
import androidx.wear.widget.WearableLinearLayoutManager;
import androidx.wear.widget.WearableRecyclerView;
import com.example.step26listview.databinding.ActivityMainBinding;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
private ActivityMainBinding binding;
WearableRecyclerView recyView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
recyView=binding.recyView;
//아이템이 가운데 정렬되도록 설정
recyView.setEdgeItemsCenteringEnabled(true);
//레이아웃 매니저 설정
recyView.setLayoutManager(new WearableLinearLayoutManager(this));
//출력할 Data(모델)
List<String> names=new ArrayList<>();
names.add("바나나");
names.add("딸기");
names.add("복숭아");
names.add("사과");
names.add("오렌지");
names.add("무화과");
names.add("포도");
names.add("레몬");
names.add("라임");
//RecyclerView에 연결할 아답타 객체 생성
RecyAdapter adapter=new RecyAdapter(names);
//RecyclerView에 아답타 연결
recyView.setAdapter(adapter);
recyView.setHasFixedSize(true);
}
}
- recyView 바인딩 해주기
//아이템이 가운데 정렬되도록 설정
recyView.setEdgeItemsCenteringEnabled(true);
//레이아웃 매니저 설정
recyView.setLayoutManager(new WearableLinearLayoutManager(this));
- 아이템이 가운데 오도록 설정해 주어야 한다.
- 원형에는 잘리는 부분이 생기므로 필요!
- 이런 형태로 RecyclerView에 친구목록을 출력하고, 클릭하면 정보를 보여주도록 할 것이다!
- 리스트뷰를 사용하는 것이라고 생각하기! 구조는 똑같다.
- 데이터를 아답타에, 아답타를 RecyclerView에 연결하면 데이터가 View에 출력된다.
RecyAdapter
package com.example.step26listview;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class RecyAdapter extends RecyclerView.Adapter<RecyAdapter.ViewHolder> {
//모델
private List<String> localDataSet;
//생성자의 인자로 모델을 전달받아서 필드에 저장
public RecyAdapter(List<String> dataSet){
localDataSet=dataSet;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//res/layout/cell.xml 문서를 전개해서 View 객체를 만들고
View view= LayoutInflater.from(parent.getContext())
.inflate(R.layout.cell, parent, false);
//해당 View 객체를 이용해서 ViewHolder 객체를 생성해서 리턴한다.
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
//ViewHolder가 가지고있는 TextView의 참조값을 얻어와서
//position에 해당하는 데이터를 출력한다.
holder.getTextView().setText(localDataSet.get(position));
}
@Override
public int getItemCount() {
//모델의 개수를 리턴
return localDataSet.size();
}
//ViewHolder 내부 클래스
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView textView;
public ViewHolder(View view) {
super(view);
textView = (TextView) view.findViewById(R.id.textView);
}
public TextView getTextView() {
return textView;
}
}
}
- RecyclerView.Adapter<> 를 상속받아서 만든 아답타!
- 이 Adapter 안에서 클래스를 정의한다.
- static 클래스를 하나 만들어주고, RecyclerView.Adapter<> 의 제네릭 타입을 정의한다.
- 필요한 추상메소드도 오버라이드!
- 연결할 텍스트뷰를 하나 만들어 주어야 한다.(ListView의 cell역할)
- layout-new-LayoutResource File 으로 생성
- 리니어 레이아웃으로 cell 생성
cell.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView"
android:textAlignment="center"/>
</LinearLayout>
- 이것이 시계에서 하나하나 돌리면서 보여줄 셀이 된다.
- 생성자의 인자로 모델을 전달받아서 필드에 넣는다.
- ViewHolder 객체를 만들어서 리턴해준다.
- onCreateViewHolder 안에서 cell을 전개해서 View를 만들고, 리턴해서 나온 값을 ViewHolder 내부클래스에 전달한다
- 아래 메소드를 사용해서 값을 얻어오는 것이다.
(private로 되어있어서 필드에 직접 접근할 수가 없다)
- 리스트의 친구들(아이템)이 회전되어 하나씩 보인다.
recyView.setHasFixedSize(true);
- RecyclerView 안의 아이템의 크기를 일정하게 한다(크기 명시하기)
- 이렇게 명시해두면 매번 새로 그리는 (성능이 떨어지는) 작업을 하지않아도 된다.
- 이렇게 리스트를 출력해준다.
- 화면이 좁아서 UI가 특이한 편이다. UI 사용법만 잘 익히면 안드로이드 앱과 큰 차이가 없다.
'국비교육(22-23)' 카테고리의 다른 글
119일차(1)/Android App(76) : apk 파일 생성, 수동으로 구동시키기 (0) | 2023.03.31 |
---|---|
118일차(1)/Android App(75) : Wearable App 예제(2), 기기 페어링 (1) | 2023.03.30 |
117일차(1)/CSS(16) : CSS3 Flex 활용(4) (0) | 2023.03.28 |
116일차(1)/CSS(15) : CSS3 Flex 활용(3) (0) | 2023.03.27 |
115일차(1)/CSS(14) : CSS3 Flex 활용(2) (0) | 2023.03.26 |