簡體   English   中英

即使在onCreateView中初始化后,android片段視圖也會拋出空指針異常

[英]android fragment view throw null pointer exception even after being initialized in onCreateView

這里我有一個片段交互,如果點擊回收器視圖項,它會將數據傳遞給MainActivity ,然后MainActivity調用DetailFragment.updateText()方法來更新它的視圖,但即使我在onViewCreated()這樣做,視圖也沒有初始化,如果DetailFragment.updateText()在視圖初始化之前被調用,那么我如何確保在視圖初始化之后調用它們。 *注意我添加了DetailFragmentDetailActivity通過XML片段標簽,與同為ListFragmentMainActivity

主要活動

public class MainActivity extends AppCompatActivity implements ListFragment.Listener {

// the method to be called when an item in recycler view is clicked
// so i can pass this data to DetailFragment

@Override
public void listenerMethod(String firstName, String lastName) {
    DetailFragment detailFragment = new DetailFragment();
    detailFragment.updateText(firstName, lastName);
}

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

}

列表片段

public class ListFragment extends Fragment {

private static final String TAG = "ListFragment";

private RecyclerView recyclerView;
private RecyclerViewAdapter recyclerViewAdapter;

// fragment communication interface
public interface Listener {
    void listenerMethod(String firstName, String lastName);
}

private Listener listener;

@Override
public void onAttach(@NonNull Context context) {
    super.onAttach(context);
    try {
        this.listener = (Listener) context;
    } catch (ClassCastException e) {
        Log.d(TAG, "onAttach: "+ e.getMessage());
    }
}

public ListFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_list, container, false);
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    recyclerView = getView().findViewById(R.id.recyclerview);
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));


    // some dummy data to fill the recycler view
    ArrayList<User> users = new ArrayList<>();

    users.add(new User("hiwa", "jalal"));
    users.add(new User("mohammed", "abdullah"));


    recyclerViewAdapter = new RecyclerViewAdapter(users, getActivity(), listener);

    recyclerView.setAdapter(recyclerViewAdapter);
}
}

回收器視圖適配器

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

private List<User> userList;
private Context context;
private ListFragment.Listener listener;

public RecyclerViewAdapter(List<User> userList, Context context, ListFragment.Listener listener) {
    this.userList = userList;
    this.context = context;
    this.listener = listener;

}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_row
            , parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

    User user = userList.get(position);
    holder.tvFirstName.setText(user.getFirstName());
    holder.tvLastName.setText(user.getLastName());


}

@Override
public int getItemCount() {
    return userList.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {

    public TextView tvFirstName;
    public TextView tvLastName;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);
        tvFirstName = itemView.findViewById(R.id.row_first_name);
        tvLastName = itemView.findViewById(R.id.row_last_name);

 itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          User user = userList.get(getAdapterPosition);

            listener.listenerMethod(user.getFirstName(), user.getLastName());
        }
    });


    }
}
}

細節片段

public class DetailFragment extends Fragment {

private TextView tvFirstName;
private TextView tvLastName;

public DetailFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_detail, container, false);
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    tvFirstName = view.findViewById(R.id.detail_frag_first_name);
    tvLastName = view.findViewById(R.id.detail_frag_last_name);
}

// update the details fragment views
public void updateText(String firstName, String lastName) {
    tvFirstName.setText(firstName);
    tvLastName.setText(lastName);
}

}

活動主

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context=".MainActivity">

    <fragment
        android:id="@+id/main_fragment_list"
        android:name="com.example.peacewithfragments.ListFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


</LinearLayout>

活動細節

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    tools:context=".DetailsActivity">


    <fragment
        android:id="@+id/detailsActivity_fragment_container"
        android:name="com.example.peacewithfragments.DetailFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

每次觸發偵聽器的方法時,都會創建一個 DeticalsFragment 的新實例。 如果您在布局 xml 中定義了片段,則必須從片段管理器(或在使用 AppCompatActivity 時支持片段管理器)獲取正確的片段實例。

@Override
public void listenerMethod(String firstName, String lastName) {

  // find the fragment by its id, sometihng like that
  // id is the fragments id you defined in the layout xml
  DetailsFragment detailFragment = (DetailsFragment)supportFragmentManager.findFragementById(R.id.frag_details);
  detailFragment.updateText(firstName, lastName);
}

您不能從MainActivity直接訪問DetailFragment ,因為它不是MainActivity的一部分。 因此,首先您必須導航到DetailActivity然后訪問DetailFragment 檢查以下:

public class MainActivity extends AppCompatActivity implements ListFragment.Listener {

    private DetailFragment detailFragment;

    @Override
    public void listenerMethod(String firstName, String lastName) {
        if(detailFragment != null) {
            detailFragment.updateText(firstName, lastName);
        } else {
            Intent detailIntent = new Intent(this, DetailsActivity.class);
            detailIntent.putExtra("FirstName", firstName);
            detailIntent.putExtra("LastName", lastName);

            startActivity(detailIntent);
        }
    }

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

        View view = findViewById(R.id.tablet_detail_container);
        if (view != null) {
            detailFragment = new DetailFragment();

            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();


            transaction.add(R.id.tablet_detail_container, detailFragment);
            transaction.addToBackStack(null);
            transaction.commit();
        }
    }
}

然后在您的DetailsActivity接受那些額外的並將其傳遞給DetailFragment如下所示:

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

    ...

    String firstName = getIntent().getStringExtra("FirstName");
    String lastName = getIntent().getStringExtra("LastName");

    DetailFragment detailFragment = getSupportFragmentManager().findFragmentById(R.id.detailsActivity_fragment_container);

    if(detailFragment != null)
        detailFragment.updateText(firstName, lastName);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM