특수한 포인터onCreate()의 뷰에 액세스하는 예외
이것은 StackOverflow에서 자주 발생하는 문제에 대한 표준 질문입니다.
저는 튜토리얼을 따라하고 있어요.마법사를 사용하여 새 작업을 만들었습니다.NullPointerException
의 할 때View
「」로 findViewById()
중에onCreate()
.
★★onCreate()
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View something = findViewById(R.id.something);
something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
XML('XML')fragment_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="packagename.MainActivity$PlaceholderFragment" >
<View
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/something" />
</RelativeLayout>
자습서가 오래되어 마법사 생성 코드에서 선호하는 조각 기반 UI 대신 활동 기반 UI를 생성하려고 시도한 것 같습니다.
레이아웃프래그먼트)에 .fragment_main.xml
레이아웃에 ).activity_main.xml
onCreate()
은 라이프 이 너무 뷰 수 또, 「액티비티 뷰」의 계층에서는 찾을 수 없습니다.null
이 반환됩니다.에서 null
NPE를 사용하다
를 fragment 「는 fragment입니다.onCreateView()
, 호출, 호출findViewById()
rootView
:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
View something = rootView.findViewById(R.id.something); // not activity findViewById()
something.setOnClickListener(new View.OnClickListener() { ... });
return rootView;
}
으로 액티비티 뷰가 되어 액티비티와 할 수 있게 .findViewById()
, 에만 fragment가 실행됩니다. 중인 은 fragment로 됩니다.super.onStart()
후에onCreate()
.
방법을 시도하고 사용하세요.
View view = getView().findViewById(R.id.something);
any 할 때 anyould any view view are any view.getView().findViewById
에 있어서의 방법.
by "클릭 리스너"를 합니다.anyView.setOnClickListener(this);
액세스 뷰를 fragment의 onViewCreated 메서드로 전환합니다.onCreate 메서드로 뷰에 액세스하려고 하면 늘 포인터 예외가 발생할 때 뷰가 렌더링되지 않을 수 있습니다.
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
View something = findViewById(R.id.something);
something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
동의해요, 이것은 전형적인 오류입니다. 왜냐하면 사람들은 Android 개발을 시작할 때 Fragments가 어떻게 작동하는지 잘 모르기 때문입니다.혼란을 완화하기 위해 원래 Application is stopp in adroid emulator에 올린 간단한 예시 코드를 만들었는데, 여기도 올렸습니다.
예를 들어 다음과 같습니다.
public class ContainerActivity extends FragmentActivity implements ExampleFragment.Callback
{
@Override
public void onCreate(Bundle saveInstanceState)
{
super.onCreate(saveInstanceState);
this.setContentView(R.layout.activity_container);
if (saveInstanceState == null)
{
getSupportFragmentManager().beginTransaction()
.add(R.id.activity_container_container, new ExampleFragment())
.addToBackStack(null)
.commit();
}
getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener()
{
public void onBackStackChanged()
{
int backCount = getSupportFragmentManager().getBackStackEntryCount();
if (backCount == 0)
{
finish();
}
}
});
}
@Override
public void exampleFragmentCallback()
{
Toast.makeText(this, "Hello!", Toast.LENGTH_LONG).show();
}
}
activity_syslog.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="@+id/activity_container_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
예: 플래그먼트:
public class ExampleFragment extends Fragment implements View.OnClickListener
{
public static interface Callback
{
void exampleFragmentCallback();
}
private Button btnOne;
private Button btnTwo;
private Button btnThree;
private Callback callback;
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
try
{
this.callback = (Callback) activity;
}
catch (ClassCastException e)
{
Log.e(this.getClass().getSimpleName(), "Activity must implement Callback interface.", e);
throw e;
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_example, container, false);
btnOne = (Button) rootView.findViewById(R.id.example_button_one);
btnTwo = (Button) rootView.findViewById(R.id.example_button_two);
btnThree = (Button) rootView.findViewById(R.id.example_button_three);
btnOne.setOnClickListener(this);
btnTwo.setOnClickListener(this);
btnThree.setOnClickListener(this);
return rootView;
}
@Override
public void onClick(View v)
{
if (btnOne == v)
{
Toast.makeText(getActivity(), "One.", Toast.LENGTH_LONG).show();
}
else if (btnTwo == v)
{
Toast.makeText(getActivity(), "Two.", Toast.LENGTH_LONG).show();
}
else if (btnThree == v)
{
callback.exampleFragmentCallback();
}
}
}
fragment_fragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/example_button_one"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:text="@string/hello"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"/>
<Button
android:id="@+id/example_button_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/example_button_one"
android:layout_alignRight="@+id/example_button_one"
android:layout_below="@+id/example_button_one"
android:layout_marginTop="30dp"
android:text="@string/hello" />
<Button
android:id="@+id/example_button_three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/example_button_two"
android:layout_alignRight="@+id/example_button_two"
android:layout_below="@+id/example_button_two"
android:layout_marginTop="30dp"
android:text="@string/hello" />
</RelativeLayout>
이것은 유효한 예이며 액티비티를 사용하여 fragment를 표시하고 fragment 내의 이벤트를 처리하는 방법을 보여줍니다.또한 포함된 활동과 통신하는 방법도 설명합니다.
뷰 "something"은 fragment화되어 있고 액티비티가 아니기 때문에 액티비티에서 액세스하는 대신 다음과 같이 fragment 클래스에서 액세스해야 합니다.
Placeholder Fragment.class에 있습니다.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_main, container,
false);
View something = root .findViewById(R.id.something);
something.setOnClickListener(new View.OnClickListener() { ... });
return root;
}
에서 UI 요소에 액세스하려고 합니다.onCreate()
단, fragment뷰는 에서 작성될 수 있기 때문에 액세스하기에는 아직 이르다.onCreateView()
방법.그리고.onActivityCreated()
method는 액티비티가 이 상태에서 완전히 로드되기 때문에 이들 액션을 처리할 때 신뢰성이 높습니다.
activity_main.xml에 다음 항목을 추가합니다.
<fragment
android:id="@+id/myFragment"
android:name="packagename.MainActivity$PlaceholderFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</fragment>
에서 뷰를 선언했으므로fragment_main.xml
, NPE 를 취득할 수 있는 코드의 일부를,onCreateView()
fragment의 메서드.이것으로 문제가 해결됩니다.
위의 질문의 투고 코드에는 문제가 있습니다.즉, oncreate 메서드에서 R.layout.activity_main을 사용하고 있지만 xml 파일명은 fragment_main.xml 입니다.이것은 표시되지 않는 fragment_main.xml 파일의 뷰를 가져오려고 하고 있기 때문에 늘 포인터 예외가 발생합니다.다음과 같이 코드를 변경합니다.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);// your xml layout ,where the views are
View something = findViewById(R.id.something);
something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
중요한 것은 Null Pointer 입니다.변수를 선언하고 값을 할당하기 전에 값을 검색하려고 하면 예외가 발생합니다.
fragment에서 뷰를 사용하거나 호출할 때 onViewCreated() 메서드를 사용합니다.
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
View v = view.findViewById(R.id.whatever)
}
나도 같은 것을 가지고 있다NullPointerException
호출 후 청취자 초기화findViewById()
onCreate()
그리고.onCreateView()
방법들.
하지만 제가 이 제품을 사용해본 결과onActivityCreated(Bundle savedInstanceState) {...}
그건 효과가 있다.그래서, 나는 그 컴퓨터에 접속할 수 있었다.GroupView
제 청취자를 설정해 주세요.
도움이 됐으면 좋겠어요.
거의 모든 개발자가 사용하는 보기를 찾기 위한 가장 인기 있는 라이브러리입니다.
내가 할 수 있는 한 그들은 적절한 방법론과 함께 관점을 찾는 것을 설명하는 충분한 대답이다.하지만 안드로이드 개발자와 매일 코드 작업을 자주 한다면 버터 나이프를 사용하면 뷰 검색에 많은 시간을 절약할 수 있고 코드를 쓸 필요가 없습니다. 2-3단계로 뷰를 밀리초 안에 찾을 수 있습니다.
앱 수준 그라데이션에 종속성 추가:
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
버터 나이프용 플러그인 추가:
File -> Settings -> plugins->
그런 다음 Android ButterKnife Zellezny를 검색하여 플러그인을 설치하고 스튜디오를 재시작하면 됩니다.
이제 액티비티의 Oncreate method로 이동하여 layout_name을 마우스 오른쪽 버튼으로 클릭하고 generate 버튼을 누른 후 버터나이프 주입 옵션을 선택하면 다음과 같이 뷰 참조가 자동으로 생성됩니다.
@BindView(R.id.rv_featured_artist)
ViewPager rvFeaturedArtist;
@BindView(R.id.indicator)
PageIndicator indicator;
@BindView(R.id.rv_artist)
RecyclerView rvArtist;
@BindView(R.id.nsv)
NestedScrollingView nsv;
@BindView(R.id.btn_filter)
Button btnFilter;
언급URL : https://stackoverflow.com/questions/23653778/nullpointerexception-accessing-views-in-oncreate
'itsource' 카테고리의 다른 글
Java를 사용하여 파일을 잠그는 방법(가능한 경우) (0) | 2022.11.26 |
---|---|
JavaScript에서 정의되지 않은 변수 또는 null 변수를 확인하는 방법은 무엇입니까? (0) | 2022.11.26 |
도커 컨테이너 내에 PHP Composer를 설치하는 방법 (0) | 2022.11.26 |
도커 컨테이너 내에서 호스트 시스템의 MySQL 데이터베이스 액세스 (0) | 2022.11.26 |
요소는 (…의 경우) 루프에서 정렬됩니다. (0) | 2022.11.26 |