即使在onCreateView

时间:2019-12-02 19:12:41

标签: android android-fragments

这里我有一个片段交互,如果单击回收者视图项,它将数据传递给MainActivity,然后MainActivity调用DetailFragment.updateText()方法来更新它的视图,但是视图未初始化即使我在onViewCreated()中做到了,如果DetailFragment.updateText()在视图初始化之前被调用,那么如何确保在视图初始化后调用它们。 *注意,我通过XML片段标记将DetailFragment添加到了DetailActivity中,对于ListFragmentMainActivity

也是如此

MainActivity

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);
}

}

ListFragment

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);
}
}

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());
        }
    });


    }
}
}

DetailFragment

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);
}

}

activity_main

<?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>

activity_detail

<?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>

2 个答案:

答案 0 :(得分:2)

每次触发侦听器的方法时,都会创建DetialsFragment的新实例。如果您在布局xml中定义了片段,则必须从fragmentmanager(或在使用AppCompatActivity时使用supportFragmentManager)中获取片段的正确实例。

var manager1 = new ScheduleManagerManager<MailSender>();
manager1.JobExecuted += OnJobExecuted();

答案 1 :(得分:1)

您不能直接从DetailFragment访问MainActivity,因为它不属于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);
}