0dp를 하는이유가 뭘까?
하나 주의해야할 점은 비율을 설정하고 싶은 길이가, 가로인지 세로인지 결정해야하며 세로로 설정하였다면 weight를 주는 레이아웃의 height값은 0dp로 설정해주어야 합니다. warp_content 로 안하시길 바랍니다. wrap_content로 설정하였을 때 비율이 맞지 않는 경우가 자주 발생하니 weight를 사용하신다면 꼭 0dp 사용하셔야합니다!! 중요합니다. 더 정확하게 설정하기 위하여 상위 레이아웃에 weightSum을 사용하면 더욱 좋습니다.
출처: https://yoo-hyeok.tistory.com/56 [유혁의 개발 스토리]
implements상속은 뭘까?
사실 상속인지도 모르고 그냥 따라쳤는데 이걸 왜 쓰는지 궁금해서 찾아보았다.
먼저 , 상속이란?부모 객체의 특징(메소드, 변수) 들을 자식객체가 물려받을 수 있도록 하는것이다.이때, 상위 객체(부모)의 특징을 '새롭게 구현' 하는가, '그대로 사용'하는가에 따라서 상속의 형태가 갈리게 된다.
- extends
- 부모에서 선언/정의를 모두하며, 자식은 오버라이딩 할 필요 없이 부모의 메소드/변수를 그대로 사용할 수 있다.
- "부모의 특징을 연장해서 사용한다."라고 기억하면 될 듯!
- implements (interface 구현)
- 부모 객체는 선언만 하며, 정의는 반드시 자식이 오버라이딩해서 사용한다.
- "부모의 특징을 도구로 사용해 새로운 특징을 만들어 사용한다."라고 기억하면 될 듯!
- abstract
- extends와 interface의 혼합이다.
- extends를 사용하지만, 몇 개는 추상 메소드로 구현되어 있다.
implements의 가장 큰 특징은 이렇게 부모의 메소드를 반드시 오버라이딩(재정의)해야 한다.
또한 이 implements는 다중상속을 대신해준다.
public class Son implements Father, Mother{...}
쉽게 생각해보면, 클래스는 상속 말 그대로 받아오는건데,
임플리먼트는 쬐끔 까다로운 상속같은거네, 부모의 메소드를 언급해줘야하니까.
간단 정리
- extends는 일반 클래스와 abstract 클래스 상속에 사용되고, implement는 interface 상속에 사용된다.
- class가 class를 상속받을 땐 extends를 사용하고, interface가 interface를 상속 받을 땐 extends를 사용한다.
- class가 interface를 사용할 땐 implements를 써야하고
- interface가 class를 사용할 땐 implements를 쓸수 없다.
- extends는 클래스 한 개만 상속 받을 수 있다.
- extends 자신 클래스는 부모 클래스의 기능을 사용한다.
- implements는 여러개 사용 가능하다.
- implements는 설계 목적으로 구현 가능하다.
- implements한 클래스는 implements의 내용을 다 사용해야 한다.
extends는 클래스를 확장하는 거고 implements는 인터페이스를 구현하는 것이다.
인터페이스와 보통 클래스의 차이는 인터페이스는 정의한 메소드를 구현하지 않아도 된다. 인터페이스를 상속받는 클래스에서 인터페이스에 정의된 메소드를 구현하면 된다.
출처:
https://wooono.tistory.com/261
https://velog.io/@hkoo9329/%EC%9E%90%EB%B0%94-extends-implements-%EC%B0%A8%EC%9D%B4
코드분석 (나중에하기)
values
-colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="gray">#888</color>
<color name="blue">#0000FF</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>
themes
-themes.xml
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.CalendarViewExample" parent="Theme.AppCompat.Light.NoActionBar">
</style>
</resources>
java
CalendarAdapter.js
package com.example.calendarviewexample;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class CalendarAdapter extends RecyclerView.Adapter<CalendarViewHolder> {
private final ArrayList<String> dayOfMonth;
private final OnItemListener onItemListener;
public CalendarAdapter(ArrayList<String> dayOfMonth, OnItemListener onItemListener) {
this.dayOfMonth = dayOfMonth;
this.onItemListener = onItemListener;
}
@NonNull
@Override
public CalendarViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.calendar_cell,parent,false);
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.height = (int)(parent.getHeight()*0.166666666);
return new CalendarViewHolder(view, onItemListener);
}
@Override
public void onBindViewHolder(@NonNull CalendarViewHolder holder, int position) {
holder.dayOfMonth.setText(dayOfMonth.get(position));
}
@Override
public int getItemCount() {
return dayOfMonth.size();
}
public interface OnItemListener{
void onItemClick(int position, String dayText);
}
}
CalendarViewHolder.js
package com.example.calendarviewexample;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class CalendarViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final TextView dayOfMonth;
private final CalendarAdapter.OnItemListener onItemListener;
public CalendarViewHolder(@NonNull View itemView, CalendarAdapter.OnItemListener onItemListener) {
super(itemView);
dayOfMonth = itemView.findViewById(R.id.cellDayText);
this.onItemListener = onItemListener;
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
onItemListener.onItemClick(getAdapterPosition(),(String)dayOfMonth.getText());
}
}
MainActivity.js
package com.example.calendarviewexample;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.time.LocalDate;
import java.time.Year;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
public class MainActivity extends AppCompatActivity implements CalendarAdapter.OnItemListener{
private TextView monthYearText;
private RecyclerView calendarRecyclerView;
private LocalDate selectedDate;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initWidgets();
selectedDate = LocalDate.now();
setMonthView();
}
private void setMonthView() {
monthYearText.setText(monthYearFromDate(selectedDate));
ArrayList<String> daysInMonth = daysInMonthArray(selectedDate);
CalendarAdapter calendarAdapter = new CalendarAdapter(daysInMonth, this);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),7);
calendarRecyclerView.setLayoutManager(layoutManager);
calendarRecyclerView.setAdapter(calendarAdapter);
}
private ArrayList<String> daysInMonthArray(LocalDate date) {
ArrayList<String> daysInMonthArray = new ArrayList<>();
YearMonth yearMonth = YearMonth.from(date);
int daysInMonth = yearMonth.lengthOfMonth();
LocalDate firstOfMonth = selectedDate.withDayOfMonth(1);
int dayOfWeek = firstOfMonth.getDayOfWeek().getValue();
for(int i=1; i<=42; i++){
if(i<=dayOfWeek || i > daysInMonth+dayOfWeek)
{
daysInMonthArray.add("");
}else{
daysInMonthArray.add(String.valueOf(i - dayOfWeek));
}
}return daysInMonthArray;
}
private String monthYearFromDate(LocalDate date){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM yyyy");
return date.format(formatter);
}
private void initWidgets() {
calendarRecyclerView = findViewById(R.id.calendarRecyclerView);
monthYearText = findViewById(R.id.monthYearTV);
}
public void previousMonthAction(View view) {
selectedDate = selectedDate.minusMonths(1);
setMonthView();
}
public void nextMonthAction(View view) {
selectedDate= selectedDate.plusMonths(1);
setMonthView();
}
@Override
public void onItemClick(int position, String dayText) {
if(dayText.equals("")){
String message = "Selected Date" + dayText + " "+monthYearFromDate(selectedDate);
Toast.makeText(this,message,Toast.LENGTH_LONG).show();
}
}
}
layout
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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="20dp"
android:layout_marginTop="20dp">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/back"
android:textColor="@color/blue"
android:background="@null"
android:textStyle="bold"
android:onClick="previousMonthAction"
android:textSize="20sp"/>
<TextView
android:id="@+id/monthYearTV"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:text="Aug 2021"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:textAlignment="center"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/forward"
android:textColor="@color/blue"
android:background="@null"
android:textStyle="bold"
android:onClick="nextMonthAction"
android:textSize="20sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="일"
android:textColor="@color/gray"
android:textAlignment="center"
android:textSize="16sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="월"
android:textColor="@color/gray"
android:textAlignment="center"
android:textSize="16sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="화"
android:textColor="@color/gray"
android:textAlignment="center"
android:textSize="16sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="수"
android:textColor="@color/gray"
android:textAlignment="center"
android:textSize="16sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="목"
android:textColor="@color/gray"
android:textAlignment="center"
android:textSize="16sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="금"
android:textColor="@color/gray"
android:textAlignment="center"
android:textSize="16sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="토"
android:textColor="@color/gray"
android:textAlignment="center"
android:textSize="16sp"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/calendarRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
calendar_cell.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/cellDayText"
android:text="1"
android:textSize="20sp"
android:textColor="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintVertical_bias="0.25"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
결과
추가해야할 기능
- 날짜 선택
- 날짜 선택하면 밑에 뜨게
참고
https://www.youtube.com/watch?v=Ba0Q-cK1fJo
'✍2021,2022 > app(android studio)' 카테고리의 다른 글
앱만들기.32(constraint Layout) (0) | 2021.08.04 |
---|---|
앱만들기.32(VideoView) (0) | 2021.08.04 |
앱만들기.30(Broadcastreceiver) (0) | 2021.08.03 |
앱만들기.28(Login&Register)[하다말았음] (0) | 2021.08.03 |
앱만들기29.(RelativeLayout) (0) | 2021.08.03 |