programing

findViewById()는 다른 구성 요소가 아닌 레이아웃 XML의 사용자 지정 구성 요소에 대해 null을 반환합니다.

elecom 2023. 10. 30. 20:33
반응형

findViewById()는 다른 구성 요소가 아닌 레이아웃 XML의 사용자 지정 구성 요소에 대해 null을 반환합니다.

는 는이 있습니다.res/layout/main.xml다음 요소 및 기타를 포함합니다.

<some.package.MyCustomView android:id="@+id/foo" (some other params) />
<TextView android:id="@+id/boring" (some other params) />

생성 시 활동에서 다음 작업을 수행합니다.

setContentView(R.layout.main);
TextView boring = (TextView) findViewById(R.id.boring);
// ...find other elements...
MyCustomView foo = (MyCustomView) findViewById(R.id.foo);
if (foo == null) { Log.d(TAG, "epic fail"); }

다른 요소는 성공적으로 찾았지만,foonull로 돌아옵니다.My My CustomView다가 .MyCustomView(Context c, AttributeSet a)그리고.Log.d(...)해당 생성자가 끝날 때 "epic 실패" 직전에 logcat에 성공적으로 나타납니다.

요?foo무효라고요?

왜냐하면 시공자 안에서, 저는super(context)대신에super(context, attrs).

id와 같은 특성을 전달하지 않으면 보기에 id가 없으므로 해당 id를 사용하여 찾을 수 없습니다. :-)

사용자 지정 보기에서 생성자를 무시했지만 슈퍼 생성자를 호출하지 않고 호출했기 때문에 동일한 문제가 발생했습니다.attrs은 복사 parameter. (복사/붙여넣기 실수였습니다.)

이전 생성자 버전:

public TabsAndFilterRelativeLayout(Context context, AttributeSet attrs) {
    super(context);
}

이제 나는 다음과 같은 것이 있습니다.

public TabsAndFilterRelativeLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

그것도 효과가 있어요!

다양한 이유가 있는 것 같습니다.전 그냥 "클린..." 이클립스에서 비슷한 문제를 해결합니다. (FindViewBy)이전에 ID가 작동했고 어떤 이유로 null을 반환하기 시작했습니다.)

저도 같은 문제가 있었습니다.제 실수는 다음과 같습니다.

        LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View layout=inflater.inflate(R.layout.dlg_show_info, null);
        alertDlgShowInfo.setView(layout);
        TableRow trowDesc=(TableRow)findViewById(R.id.trowDesc);

인플레이터를 사용하여 XML 파일에서 뷰를 "로드"하는 과정에서 마지막 줄이 잘못되었습니다.이 문제를 해결하기 위해서는 다음과 같이 써야 했습니다.

TableRow trowDesc=(TableRow)layout.findViewById(R.id.trowDesc);

저는 누군가가 같은 문제를 가지고 있을 경우를 대비해 제 해결책을 썼습니다.

동일한 문제이지만 다른 솔루션:전화 안 했어요.

setContentView(R.layout.main)

여기에 명시된 바와 같이 뷰를 찾으려고 시도하기 전에

여러 레이아웃 버전이 있는 경우(화면 밀도, SDK 버전에 따라 다름), 모든 버전에 원하는 요소가 포함되어 있는지 확인합니다.

사용자 지정 보기가 메인 XML에서 다음과 같이 보였기 때문에 findViewById가 null로 반환되었습니다.

        <com.gerfmarquez.seekbar.VerticalSeekBar  
            android:id="@+id/verticalSeekBar"
            android:layout_width="wrap_content" 
            android:layout_height="fill_parent" 
            />

xmlns 항목을 추가하면 다음과 같이 작동한다는 것을 알게 되었습니다.

        <com.gerfmarquez.seekbar.VerticalSeekBar  
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/verticalSeekBar"
            android:layout_width="wrap_content" 
            android:layout_height="fill_parent" 
            />

꼭 확인해주세요.setContentView(R.layout.main)전표호출전findViewById(...)성명서;

저는 프로젝트 설정에서 자바 빌드 경로의 소스에 res 폴더를 추가하면 문제가 해결되었습니다.

얼마 전 레이아웃 XML을 통해 사용자 지정 View를 추가한 다음 애플리케이션의 다른 곳에 콜백을 첨부하려고 했을 때 동일한 문제가 발생했습니다.

사용자 지정 보기를 만들어 "layout_main.xml"에 추가했습니다.

public class MUIComponent extends SurfaceView implements SurfaceHolder.Callback {
    public MUIComponent (Context context, AttributeSet attrs ) {
        super ( context, attrs );
    }
    // ..
}

그리고 메인 액티비티에서는 콜백을 첨부하고 XML에서 UI 요소에 대한 참조를 얻고 싶었습니다.

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // ...

        MUIInitializer muiInit = new MUIInitializer();
        muiInit.setupCallbacks(this);
        muiInit.intializeFields(this);
    }       
}

Initilizer는 화려한 작업을 하지 않았지만 사용자 지정 보기(MUIC Component) 또는 기타 비사용자 지정 UI 요소를 변경하려고 시도한 모든 작업이 애플리케이션에 나타나지 않았습니다.

public class MUIInitializer {

    // ...

    public void setupCallbacks ( Activity mainAct ) {


        // This does NOT work properly
        // - The object instance returned is technically an instance of my "MUICompnent" view
        //   but it is a *different* instance than the instance created and shown in the UI screen
        // - Callbacks never get triggered, changes don't appear on UI, etc.
        MUIComponent badInst = (MUIComponent) mainAct.findViewById(R.id.MUIComponent_TESTSURF);


        // ...
        // This works properly

        LayoutInflater inflater = (LayoutInflater) mainAct.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View inflatedLayout = inflater.inflate ( R.layout.activity_main, null );

        MUIComponent goodInst = (MUIComponent) inflatedLayout.findViewById(R.id.MUIComponent_TESTSURF);


        // Add callbacks
        // ...
    }

}

"badInst"와 "goodInst"의 차이점은 다음과 같습니다.

  • badInst는 활동의 findViewByID를 사용합니다.
  • goodInst는 레이아웃을 부풀리고 부풀린 레이아웃을 사용하여 룩업을 수행합니다.

Wear에 대한 맞춤 구성요소로 발생한 일이지만 일반적인 조언입니다.스텁(Stub)을 사용하는 경우(예: 제가 사용하던 경우)WatchViewStub), 전화를 그냥 걸 수는 없습니다.findViewById()아무 곳이나.스터브 안에 있는 모든 것이 먼저 팽창되어야 합니다. 그 후에만 일어나는 것은 아닙니다.setContentView()을 작성해야 합니다 따라서 이런 일이 발생할 때까지 기다리려면 다음과 같은 내용을 작성해야 합니다.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_wear);
    final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
    stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
        @Override
        public void onLayoutInflated(WatchViewStub stub) {
            myCustomViewInst = (MyCustomView) findViewById(R.id.my_custom_view);
            ...

제 문제는 오타였습니다.내가 써놨었습니다.android.id에점) 대신 (android:id. :P

사용자 지정 구성 요소 xml에 구문 검사가 없는 것 같습니다. :(

같은 문제가 있었습니다.

저는 아이들이 거의 없는 레이아웃을 가지고 있었습니다.(맥락을 사용하여) 참조를 얻기 위해 그것들 중 하나의 작성자로부터 시도하고 있었습니다.다른 자식에게 ViewById)를 찾습니다.둘째 아이가 레이아웃에 추가로 정의되어 있어서 작동하지 않았습니다.

이렇게 해결했습니다.

setContentView(R.layout.main);
MyView first = findViewById(R.layout.first_child);
first.setSecondView(findViewById(R.layout.second_child));

아이들 순서가 반대면 그것도 효과가 있겠지만, 일반적으로 위와 같이 해야 한다고 생각합니다.

findViewById()메서드가 반환되는 경우가 있습니다.null레이아웃의 루트에 아무것도 없을 때android:id기여하다.레이아웃 xml 파일을 생성하기 위한 Eclipse 마법사가 자동으로 생성되지 않음android:id루트 요소의 속성입니다.

저의 경우 뷰를 불러오려고 했던 뷰의 상위가 아닌 뷰에 있었습니다.그래서 차일드 뷰에서는 다음과 같이 전화해야 했습니다.

RelativeLayout relLayout = (RelativeLayout) this.getParent();
View view1 = relLayout.findViewById(R.id.id_relative_layout_search);

저는 '클린' 옵션이 효과가 있었습니다.

제 경우, 근본 원인은 소스 코드가 네트워크 공유에 존재하고 워크스테이션과 파일 서버가 올바르게 동기화되지 않아 5초 정도 표류했기 때문입니다.Eclipse에서 생성된 파일의 타임스탬프가 과거(파일 서버에서 할당되었기 때문에) 워크스테이션의 클럭에 있으므로 Eclipse에서 생성된 파일과 원본 파일 간의 종속성을 잘못 해결합니다.이 경우 잘못된 타임스탬프에 의존하는 증분 빌드 대신 완전한 재구성을 강제로 수행하기 때문에 '깨우기'가 작동하는 것으로 보입니다.

워크스테이션의 NTP 설정을 수정한 후 다시는 문제가 발생하지 않았습니다.NTP를 제대로 설정하지 않으면 클럭이 빠르게 이동하기 때문에 몇 시간 간격으로 발생합니다.

주의해야 할 답변에 또 다른 사소한 실수를 추가하는 방법

실제로 올바른 레이아웃 XML 파일을 편집하고 있는지 확인합니다.

모든 레이아웃 폴더에서 뷰 ID를 업데이트하는 것을 잊어버려서 동일한 문제가 발생했습니다.

언급URL : https://stackoverflow.com/questions/1691569/findviewbyid-returns-null-for-custom-component-in-layout-xml-not-for-other-co

반응형