마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

MainActivity에 있는 버튼을 SubActivity에서 보이지 않게 만들고 있습니다 [closed]

0 추천

MainActivity에 있는 버튼인 resetB 란 버튼을

SubActivity에서 INSIBLE 사용하여 보이지 않게 만들고 있습니다 

하지만 제가 잘못 작성하였는지 INSIBLE이 적용되지 않고 앱이 꺼져버립니다

아래는 SubActivity에서 resetB를 INSIBLE 시도중인 코드입니다 

무엇을 수정해야 할까요?..

 

public class SubActivity extends Activity {

    Button resetH, resetH2;
    Button resetB, miC;


    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub);
        ImageButton back = (ImageButton) findViewById(R.id.back);

        resetH = (Button) findViewById(R.id.resetH);
        resetH2 = (Button) findViewById(R.id.resetH2);
        resetB = findViewById(R.id.resetB);
        

        resetH.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View view) {
                resetB.setVisibility(View.VISIBLE);

            }
        });
        

        resetH2.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View view) {

                resetB.setVisibility(View.INVISIBLE);

            }
        });



        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                startActivity(intent);
            }
        });
질문을 종료한 이유: 문제를 해결 하였습니다
초보 개발 (120 포인트) 님이 2023년 1월 23일 질문
초보 개발님이 2023년 1월 26일 closed

2개의 답변

0 추천
resstB가  MainActivity에 있다고 했는데 왜 SubActivity의 레이아웃에서 findViewById를 하고 계시죠?

setContentView(R.layout.actvity_sub)

을 호출하고 나면 이 레이아웃에 있는 뷰들만 findViewById를 통해 찾을 수 있습니다. 만약 이 레이아웃에 없는 뷰의 경우는 findViwById를 호출하면 null이 리턴됩니다. 따라서 resetB는 널이 될 겁니다.

따라서, resetB.setVisibility(..)를 호출할 때 NullPointerException 이 발생하겠죠.

안드로이드에서 액티비티 간에 멤버 변수나 메소드를 바로 참조/호출할 수 있는 직접적인 방법이 없습니다. Intent를 통해 필요한 값을 전달하거나 아니면 startActivityForResult를 통해 SubActivity를 호추하고 setResult를 통해 값을 전달하는 두가지 방식이 흔히 사용되는 방식입니다.

첫번째 방법을 사용할 경우는 MainActivity의 onNewIntent를 오버라이드 해서 intent로부터 필요한 값을 읽어와야 하고, 두번째 방법은 onActivityResult를 오버라이드 해서 처리해야 합니다.
spark (224,800 포인트) 님이 2023년 1월 24일 답변
0 추천

 Intent 를 이용한 예제를 보여드릴게요.

AndroidManifest.xml에 액티비티를 하나만 띄우기 위해 singleTask  를 추가합니다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
...>
 
    <application
         ....>

        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

 

SubActivity의 버튼 클릭이벤트를 처리합니다. 버튼을 누를 때 MainActivity로 버튼상태를 전달합니다.

public class SubActivity extends AppCompatActivity {

    public static final String EXTRA_RESET_VISIBILITY = "ResetVisibility";

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

        setupViews();
    }

    private void setupViews() {
        findViewById(R.id.resetH).setOnClickListener(view -> {
            setVisibleReset(View.VISIBLE);
        });

        findViewById(R.id.resetH2).setOnClickListener(view -> {
            setVisibleReset(View.INVISIBLE);
        });
    }

    private void setVisibleReset(int visibility) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra(EXTRA_RESET_VISIBILITY, visibility);
        startActivity(intent);
        finish();
    }
}

 

MainActiity가 singleTask일 때는 onNewIntent메소드가 호출됩니다. 해당 메소드를 오버라이드합니다.

public class MainActivity extends AppCompatActivity {

    private Button resetB;

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

        setupViews();
    }

    private void setupViews() {
        resetB = findViewById(R.id.resetB);
        resetB.setOnClickListener(view -> {
            showSubActivity();
        });
    }

    private void showSubActivity() {
        Intent intent = new Intent(this, SubActivity.class);
        startActivity(intent);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        int visibility = intent.getIntExtra(SubActivity.EXTRA_RESET_VISIBILITY, View.VISIBLE);
        resetB.setVisibility(visibility);
    }
}

 

다른 추가설명없이 직관적으로 이해할 수 있는 코드입니다. 천천히 보시면 충분히 이해가 가실겁니다.

spark (224,800 포인트) 님이 2023년 1월 24일 답변
하나하나 상세하고 정확한 답변 정말 감사드립니다 새벽에 답글을 다는 건 예의가 아니지만 이제야 비로소 덕분에 문제를 해결 할 수 있었습니다 정말 감사 드립니다
...