[AndroidStudio] KnockKock 개발일지 -0218(BottomNavigationBar A.K.A 하단바)

Hyebin Lee·2022년 2월 20일
0
post-thumbnail

오늘의 목표

  1. ✔하단바 만들기 (BottomNavigationBar)
  2. ✔마이페이지 생성하기
  3. 게시글 작성, 삭제, 조회에 따른 SharedPoint 기능 구현하기

참고 링크

  1. [Android Java] BottomnNavigationView를 사용하여 하단 바 생성하기
    2. [TextView] 안드로이드 TextView의 모든 것 2 - 모서리 둥글게 버튼 만들기

오늘의 이슈

  1. 교훈 메세지 하나🌱 : 실행 로그 말고 빌드 에러 로그도 잘 보자

1. 얼떨결에 하단바 문제 해결,,,?

예전에 하단바 만든다고 BottomNavigationBar 코드를 구현해놨었는데 그때 정말 알 수 없는 오류가 나서,, 코드가 잘못된 줄 알고 다 뜯어 고치려고 했더니만 오늘 보니까 dependency만 하나 수정해줬더니 바로 코드가 잘 돌아갔다..😭🥰 이거로 애먹을 각오하고 있었는데 너무 행복하다.

하지만 그렇기 때문에 하단바 생성하는 과정을 기록하지 못했다,, 원래 어느정도 진행되고 기록을 몰아서 그날그날 하는 스타일이라 뭐 하나 코드 구현할 때마다 기록하는게 아니라서,,,, 기록 데이터도 없고 머리에 남아있는 것도 없다.
그래도 기억상으로 하단바 구현이 어렵거나 복잡하지는 않았던 것 같다. 그냥 어느 잘 정리된 링크 보고 따라서 하면 금방 다시 할 수 있을거라고,, 믿어.....

implementation 'com.android.support:design:28.0.0'

build.gradle(module:app) 설정 파일의 의존성에 위의 코드를 추가해줬더니 에러는 해결되었다.
그 당시에 에러가 너무 원인을 종잡을 수 없게 나서 도저히 손델 수 없다고 생각했는데 오늘 보니까 바로 build 에러가 나서 바로 찾아낼 수 있었다.
그때는 왜 build 에러가 똑같이 안났을까,, 내가 못찾았나...? 정말 알 수가 없다.

2. 마이페이지 구현

하단바를 구현할 때 이미 구현한 코드이지만 어차피 지금 다시 보면서 이해가 필요해서 겸사겸사 정리한다.
먼저 MainActivity를 아래 코드와 같이 작성했다. 이제 기존의 Activity의 역할은 fragment가 대신 해주고 이 Activity는 fragment들을 올릴 용도로만 사용한다. 따라서 내용 변동 없이 앞으로 고정될 것이다. (아마도)
이 Activity에서는 하단바에 해당하는 내용만 구현해주면 된다.

MainActivity 코드 내용

package org.techtown.knockknock;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.MenuItem;
import android.widget.LinearLayout;

import com.google.android.material.bottomnavigation.BottomNavigationView;

import org.techtown.knockknock.message.MessageFragment;
import org.techtown.knockknock.user.MypageFragment;

public class MainActivity extends AppCompatActivity {
    final String TAG = this.getClass().getSimpleName();

    LinearLayout home_ly;
    BottomNavigationView bottomNavigationView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.navigationbar);

        init(); // 객체 정의
        SettingListener(); // 객체등록

        //맨처음 시작할 탭 설정
        bottomNavigationView.setSelectedItemId(R.id.tab_home);
    }
    private void init(){
        home_ly = findViewById(R.id.home_ly);
        bottomNavigationView = findViewById(R.id.bottomNavigationView);
    }
    private void SettingListener(){
        bottomNavigationView.setOnNavigationItemSelectedListener(new TabSelectedListener());
    }

    class TabSelectedListener implements BottomNavigationView.OnNavigationItemSelectedListener{

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch(item.getItemId()){
                case R.id.tab_home:{
                    getSupportFragmentManager().beginTransaction()
                            .replace(R.id.home_ly,new HomeFragment())
                            .commit();
                    return true;
                }
                case R.id.tab_message:{
                    getSupportFragmentManager().beginTransaction()
                            .replace(R.id.home_ly,new MessageFragment())
                            .commit();
                    return true;
                }
                case R.id.tab_mypage:{
                    getSupportFragmentManager().beginTransaction()
                            .replace(R.id.home_ly,new MypageFragment())
                            .commit();
                    return true;
                }
            }
            return false;
        }
    }
}

MyPageFragment 구현

public class MypageFragment extends Fragment {

    TextView tv_nickname;
    TextView tv_userId;
    TextView tv_sharedPoint;
    LinearLayout ly_mypost;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View mView = inflater.inflate(R.layout.fragment_mypage,null); //📌올릴 frgament layout
        SharedPreferences sharedPreferences = this.getActivity().getSharedPreferences("UserInfo",MODE_PRIVATE);
        String nickname = sharedPreferences.getString("nickname","");
        String id = sharedPreferences.getString("userId","");
        int point = sharedPreferences.getInt("point",0);

        if(mView != null) {tv_nickname = (TextView)mView.findViewById(R.id.tv_mypage_nickname);
        tv_userId = (TextView)mView.findViewById(R.id.tv_mypage_id);
        tv_sharedPoint = (TextView)mView.findViewById(R.id.tv_mypage_point);
        ly_mypost = (LinearLayout)mView.findViewById(R.id.ly_button_mypost);}


        tv_nickname.setText(nickname);
        tv_userId.setText(id);
        tv_sharedPoint.setText(Integer.toString(point)+"point");

        return mView; //📌설정을 모두 마친 fragment 올리기 
    }
}

오늘의 뻘짓😭

fragment 개념을 잘 몰라서,, 그런지 한참 헤맸다.
일단 📌핀 꽂아있는 부분을 자동완성이나 복붙으로 해결하려 하다 보니까 막 이상한 layout 설정해놓거나,, return 에서 아예 새로운 초기화된 layout을 return 해버려서 textview 변경이 반영이 안되거나.. 대환장이였다.
fragment 개념은 개발하면서 차차 익혀가겠지,, 몰라유

textView를 버튼으로 customize 하기

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="false" android:state_pressed="false">
        <shape>
            <solid android:color="@android:color/holo_green_light"/>
<!--            <stroke android:color="@android:color/holo_green_dark"-->
<!--                android:width="1dp"/>-->
            <corners android:radius="30dp" />
        </shape>
    </item>
</selector>

요런식으로 drawable 폴더에다가 만들고 싶은 모양을 추가한다.

  • solid: 버튼의 색
  • stroke: 버튼의 테두리
  • corners: 끝을 둥근 모양으로 만들기 (둥근 정도)
android:background="@drawable/bg_custom_button_pay"
                android:clickable="true"
                android:focusable="true"
                android:foreground="?android:attr/selectableItemBackground"

그리고 xml의 textView에서
위에서 만든 drawable 을 background로 설정하고 클릭을 활성화 시키기 위해 아래 세 줄을 추가한다.

Fragment 간의 이동

  1. 먼저 MainActivity 혹은 fragment가 올라가는 Activity에 다음 코드를 추가한다.
public void replaceFragment(Fragment fragment){
        getSupportFragmentManager().beginTransaction().replace(R.id.home_ly,fragment).commit(); //home_ly는 fragment가 올라갈 MainActivity의 layout 아이디
    }

이 코드는 입력값으로 들어온 fragment를 home_ly에 띄워주는 코드이다.
2. 각 fragment(혹은 이동할 fragment) 마다 newInstance()함수 생성하기

public static UserPostFragment newInstance() {

        Bundle args = new Bundle();

        UserPostFragment fragment = new UserPostFragment();
        fragment.setArguments(args);
        return fragment;
    }

replaceFragment 함수를 쓰려면 input 값으로 새로운 fragment가 들어와야 하기 때문에 newInstance 함수로 새로운 fragment를 만들어서 return 해주도록 한다.

  1. 각 fragment에서 다른 fragment로 이동하고 싶을 때 위의 함수 쓰기
ly_mypost.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ((MainActivity)getActivity()).replaceFragment(UserPostFragment.newInstance());
            }
        });

이런식으로 써주면 된다.

0개의 댓글