● 메뉴탭 만들기
1.
2.
3.
4.
메뉴모양 리소스 파일 XML 코드
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/item1"
android:icon="@android:drawable/sym_action_call"
android:title="연락처" />
<item
android:id="@+id/item2"
android:icon="@android:drawable/presence_audio_online"
android:title="인터넷" />
<item
android:id="@+id/item3"
android:icon="@android:drawable/presence_video_online"
android:title="카메라" />
</menu>
● 각 탭들의 Fragment만들기
ContactFragment
WebFragment
CameraFragment
● 메뉴탭 화면
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".KakaoActivity">
<FrameLayout
android:id="@+id/fl"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/btnNav"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</FrameLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/btnNav"
android:layout_width="0dp"
android:layout_height="64dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/kakao_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 메뉴탭 화면의 ID : - fl: 메뉴를 눌렀을 때 출력하는 Layout화면
- btnNav: 버튼들을 누르는 네비게이션뷰 바
● 연락처 화면 fragment
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".ContactFragment">
<ListView
android:id="@+id/lvContact"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/btnContact"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/etContact"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="010-"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btnContact"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/btnContact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="추가"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 메뉴탭-연락처 화면의 ID : - lvContact: 연락처를 추가 했을때 추가되는 리스트 뷰
- etContact: 연락처를 입력하는 텍스트 창
- btnContact: 연락처를 추가하는 버튼
● 인터넷 화면 fragment
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".WebFragment">
<WebView
android:id="@+id/wv"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="1dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 메뉴탭- 인터넷 화면의 ID : - wv: 인터넷창을 보여주는 web 뷰
● 카메라 화면 fragment
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".CameraFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/textView2"
android:layout_width="100dp"
android:layout_height="100dp"
android:text="카메라 페이지입니다"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 메뉴탭- 카메라 화면의 ID : - textview: 카메라의 화면을 보여줌.
● 메뉴탭 Activity
package com.example.ex221004;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import android.os.Bundle;
import android.view.MenuItem;
import com.example.ex221004.databinding.ActivityKakaoBinding;
import com.google.android.material.navigation.NavigationBarView;
public class KakaoActivity extends AppCompatActivity {
ActivityKakaoBinding binding;
// Fragment 선언
ContactFragment contactFragment;
WebFragment webFragment;
CameraFragment cameraFragment;
FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityKakaoBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// Fragment들의 객체 생성
contactFragment = new ContactFragment();
webFragment = new WebFragment();
cameraFragment = new CameraFragment();
// Fragment들을 관리할 FragmentManager 필요
fragmentManager = getSupportFragmentManager();
binding.btnNav.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
if(item.getItemId() == R.id.item1){
changeFragment(contactFragment);
}
else if (item.getItemId() == R.id.item2){
changeFragment(webFragment);
}else if (item.getItemId() == R.id.item3){
changeFragment(cameraFragment);
}
return true; // 각각 버튼 색 바뀜(false->true)
}
});
}
// onCreate() 끝
// 접근제한자 리턴타입 메소드이름(매개변수){실행문장}
public void changeFragment(Fragment fragment){
fragmentManager.beginTransaction().replace(R.id.fl, fragment).commit();
}
}
※ Fragment를 사용하기 위해서는 부모 Activity가 필요하다!!
- 부모 Activity-> 메뉴탭 Activity
# Fragment 선언
ContactFragment contactFragment;
WebFragment webFragment;
CameraFragment cameraFragment;
FragmentManager fragmentManager; # Fragment 매니저 선언
# Fragment들의 객체 생성
contactFragment = new ContactFragment();
webFragment = new WebFragment();
cameraFragment = new CameraFragment();
# Fragment들을 관리할 FragmentManager 필요
fragmentManager = getSupportFragmentManager();
# Nav Item을 클릭하면 다른 Fragment로 전환 네비게이션 아이템을 선택을 감지하는 리스너를 설정!!
binding.btnNav.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
if(item.getItemId() == R.id.item1){ # 연락처 버튼을 눌렀을때 contactFragment 전환
changeFragment(contactFragment);
}
else if (item.getItemId() == R.id.item2){ # 인터넷 버튼을 눌렀을때 webFragment 전환
changeFragment(webFragment);
}else if (item.getItemId() == R.id.item3){ # 카메라 버튼을 눌렀을때 cameraFragment 전환
changeFragment(cameraFragment);
}
return true; # 각각 버튼 색(검은색->빨간색) 눌렀을 때 바뀜(false->true)
)
});
# Fragment 전환하기: 접근제한자 리턴타입 메소드이름(매개변수){실행문장}
public void changeFragment(Fragment fragment){
fragmentManager.beginTransaction().replace(R.id.fl, fragment).commit(); # Fragment 전환 완료
}
● 메뉴탭-ContactFragment Activity
package com.example.ex221004;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import com.example.ex221004.databinding.FragmentCameraBinding;
import com.example.ex221004.databinding.FragmentContactBinding;
import java.util.ArrayList;
public class ContactFragment extends Fragment {
// MainActivity의 binding의 이름은 ActivityKakaoBinding
FragmentContactBinding binding;
ArrayList<String> data;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentContactBinding.inflate(getLayoutInflater());
View view =binding.getRoot();
// Inflate the layout for this fragment
// Inflator
// XML file을 Java에서 접근가능하도록 객체 변환
// ViewBinding 기법 사용하기 이전;
// 3. 아이템 클래스 결정
data = new ArrayList<>();
data.add("010-1234-0000");
data.add("010-9999-8888");
data.add("010-7777-5555");
// 4. 어댑터 생성 (페이지 정보, 아이템 디자인, 아이템)
ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity().getApplicationContext(), R.layout.board_list, data);
// 5. 어댑터 부착
binding.lvContact.setAdapter(adapter);
// 6. Event 추가
binding.btnContact.setOnClickListener(v -> {
String contact = binding.etContact.getText().toString();
// 가장 하드코딩
boolean check = true;
for(int i = 0; i < data.size(); i++){
if(contact.equals(data.get(i))){
check = false;
break;
}
}
if(check == true){
data.add(contact);
adapter.notifyDataSetChanged();
}
data.add(contact);
adapter.notifyDataSetChanged();
});
binding.lvContact.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("삭제?");
builder.setMessage("지우시겠습니까?");
builder.setNegativeButton("Cancel", null);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
data.remove(position);
adapter.notifyDataSetChanged();
}
});
builder.show();
}
});
return view;
}
}
- binding = FragmentContactBinding.inflate(getLayoutInflater());
View view =binding.getRoot();
# Inflate the layout for this fragment
- Inflator
XML file을 Java에서 접근가능하도록 객체 변환
ViewBinding 기법 사용하기 이전;
※ AdapterView 사용법 6단계
1. ListView의 위치 결정
2. 항목뷰(itemView)의 디자인 레이아웃(xml) 작성
3. 아이템 결정
4. Adapter Class 구현
단, 항목 디자인이 TextView라면 생략 가능!!
왜냐하면, TextView를 구현하는 Adapter Class가 이미 만들어져 있다
이름은 ArrayAdapter
5. Adapter 생성 후 ListView에 부착
어댑터에세 넘겨줘야 할 데이터 3개
1) 페이지 정보 : getApplicationContext()
2) 항목 뷰 디자인 레이 아웃 : R.layout.board_list
3) 아이템 정보 : data
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.board_list, data);
binding.lvBoard.setAdapter(adapter);
6. ListView에 클릭 리스너, Action들을 추가!
3. 아이템 클래스 결정
data = new ArrayList<>(); # 배열 리스트 생성
data.add("010-1234-0000");
data.add("010-9999-8888");
data.add("010-7777-5555");
4. 어댑터 생성 (페이지 정보, 아이템 디자인, 아이템)
ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity().getApplicationContext(), R.layout.board_list, data); #??
5. 어댑터 부착
binding.lvContact.setAdapter(adapter); # list뷰에 어댑터를 넣는다.
6. Event 추가
binding.btnContact.setOnClickListener(v -> { # btnContact를 눌렀을때 contact에 입력한 문자(숫자)를 반환
String contact = binding.etContact.getText().toString();
// 가장 하드코딩
boolean check = true;
for(int i = 0; i < data.size(); i++){
if(contact.equals(data.get(i))){ # ? contact의 길이가 data의 길이와 같다면
check = false;
break;
}
}
if(check == true){ #
data.add(contact);
adapter.notifyDataSetChanged();
}
data.add(contact); # data 배열에 contact를 추가
adapter.notifyDataSetChanged(); # notifyDataSetChanged는 리스트의 크기와 아이템이 둘 다 변경되는 경우에 사용
});
- list뷰에 있는 연락처를 클릭했을때
binding.lvContact.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); # 팝업띄우기
builder.setTitle("삭제?");
builder.setMessage("지우시겠습니까?");
builder.setNegativeButton("Cancel", null); # Cancel일 결루 아무일도 일어나지 않음
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { # OK를 눌렀을때
@Override
public void onClick(DialogInterface dialogInterface, int i) {
data.remove(position); # 해당위치의 연락처를 삭제함
adapter.notifyDataSetChanged(); # notifyDataSetChanged는 리스트의 크기와 아이템이 둘 다 변경되는 경우에 사용
}
});
builder.show();
}
● 메뉴탭-WebFragment Activity
package com.example.ex221004;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.example.ex221004.databinding.FragmentWebBinding;
public class WebFragment extends Fragment {
FragmentWebBinding binding;
WebView wv; // 인터넷 화면을 보여줄 WebView
WebSettings webSettings; // WebView의 설정을 담고 있는 객체
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding = FragmentWebBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
wv = binding.wv;
webSettings = wv.getSettings();
webSettings.setSupportZoom(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setDomStorageEnabled(true);
webSettings.setSupportMultipleWindows(false);
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
webSettings.setCacheMode(webSettings.LOAD_CACHE_ELSE_NETWORK);
webSettings.setUseWideViewPort(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(false);
webSettings.setLoadWithOverviewMode(true);
wv.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
wv.loadUrl(url);
return true;
}
});
wv.loadUrl("http://www.naver.com/");
return view;
}
// onCreate() 끝
}
- binding = FragmentContactBinding.inflate(getLayoutInflater());
View view =binding.getRoot();
# Inflate the layout for this fragment
- Inflator
XML file을 Java에서 접근가능하도록 객체 변환
ViewBinding 기법 사용하기 이전;
- WebView wv; # 인터넷 화면을 보여줄 WebView
- WebSettings webSettings; # WebView의 설정을 담고 있는 객체
- wv = binding.wv;
webSettings = wv.getSettings();
webSettings.setSupportZoom(true); // Zoom 사용 여부
webSettings.setJavaScriptEnabled(true); // JavaScript 사용 여부
webSettings.setBuiltInZoomControls(true); // 화면 확대 축소 허용 여부
webSettings.setDomStorageEnabled(true); // 로컬 저장소 사용 여부
webSettings.setSupportMultipleWindows(false); // 멀티윈도우 사용 여부
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); // 컨텐츠 사이즈 맞추기
webSettings.setCacheMode(webSettings.LOAD_CACHE_ELSE_NETWORK); // 캐시 사용 여부
webSettings.setUseWideViewPort(true); // view port 사용 여부
webSettings.setJavaScriptCanOpenWindowsAutomatically(false); // JS가 window.open() 여부
webSettings.setLoadWithOverviewMode(true); // 메타 태그 허용 여부
- wv.setWebViewClient(new WebViewClient(){ # 페이지 컨트롤을 위한 기본적인 함수, 다양한 요청, 알림을 수신하는 기능을 한다.
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
# 만약 유저가 로딩한 컨텐츠에서 링크를 클릭할 경우에, 어떻게 할지를 override하는 것
-> 잠시 특정 웹사이트 페이지를 유저에게 보여주고, 클릭시에는 크롬같은 브라우저에서 웹서핑을 하도록 한다면, 아래와 같이 startActivity를 구현
wv.loadUrl(url);
return true;
}
});
- wv.loadUrl("http://www.naver.com/"); # 네이버 페이지를 Load
● 메뉴탭-CameraFragment Activity
package com.example.ex221004;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.ex221004.databinding.FragmentCameraBinding;
public class CameraFragment extends Fragment {
FragmentCameraBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding = FragmentCameraBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
return view;
}
}
- binding = FragmentContactBinding.inflate(getLayoutInflater());
View view =binding.getRoot();
# Inflate the layout for this fragment
- Inflator
XML file을 Java에서 접근가능하도록 객체 변환
ViewBinding 기법 사용하기 이전;
'개발 공부 > 안드로이드 스튜디오(코틀린)' 카테고리의 다른 글
안드로이드스튜디오(notifyDataSetChanged) (0) | 2023.10.18 |
---|---|
안드로이드스튜디오(ListView, ArrayAdator 사용) (0) | 2023.10.18 |
안드로이드 스튜디오(gson사용법) (0) | 2023.10.18 |
안드로이드 스튜디오(SharedPreferences란?) (0) | 2023.10.18 |
안드로이드 스튜디오(랜덤색바꾸기) (0) | 2023.10.18 |