Android-在片段之间通信,适配器为空
我已经寻找了一段时间的答案,但我还没有找到相同的情况,所以我将尝试在这里询问 我目前正在创建一个带有活动、2个片段和viewpager功能的应用程序。片段1有一个按钮,它将更新片段2上的列表(通常的方式是,frag 1->activity->frag 2),当它到达该方法并调用notifyDataSetChanged时,它会崩溃,因为适配器为null。显然,适配器是空的,用于填充listview的现有列表是空的(这不是什么大问题,因为它会再次被填充,但我希望保留原始项) 如何更新我的列表以及为什么我的适配器为空 我的代码: 主要活动Android-在片段之间通信,适配器为空,android,android-fragments,android-viewpager,notifydatasetchanged,Android,Android Fragments,Android Viewpager,Notifydatasetchanged,我已经寻找了一段时间的答案,但我还没有找到相同的情况,所以我将尝试在这里询问 我目前正在创建一个带有活动、2个片段和viewpager功能的应用程序。片段1有一个按钮,它将更新片段2上的列表(通常的方式是,frag 1->activity->frag 2),当它到达该方法并调用notifyDataSetChanged时,它会崩溃,因为适配器为null。显然,适配器是空的,用于填充listview的现有列表是空的(这不是什么大问题,因为它会再次被填充,但我希望保留原始项) 如何更新我的列表以及为什
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
public class MainActivity extends FragmentActivity implements FirstFragment.OnUpdatedListListener {
private ViewPager viewPager;
private TestAdapter mAdapter;
//Lifecycle functions
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.TestPager);
mAdapter = new TestAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
@Override
public void onPageSelected(int position) {}
@Override
public void onPageScrollStateChanged(int state) {}
});
}
@Override
public void onListUpdated() {
logcat("Click received in main");
SecondFragment sf = SecondFragment.newInstance();
if (sf == null || !sf.isInLayout()) {
logcat("frag == null || !frag.isInLayout()");
SecondFragment newFragment = SecondFragment.newInstance();
Bundle args = new Bundle();
newFragment.setArguments(args);
android.support.v4.app.FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.second_fragment, newFragment);
transaction.addToBackStack(null);
transaction.commit();
newFragment.receiver();
} else {
logcat("frag bestaat");
sf.receiver();
}
}
}
ListItemAdapter:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.List;
public class ListItemAdapter extends ArrayAdapter<ListItem> {
private final Context context;
private List<ListItem> items;
public ListItemAdapter(Context context, int resource, List<ListItem> values) {
super(context, R.layout.list_items, values);
this.context = context;
this.items = values;
}
private static class ViewHolder {
TextView tvName;
TextView tvDescription;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.list_items, parent, false);
ViewHolder viewholder = new ViewHolder();
viewholder.tvName = (TextView) rowView.findViewById(R.id.tvName);
viewholder.tvDescription = (TextView) rowView.findViewById(R.id.tvDescription);
rowView.setTag(viewholder);
}
ViewHolder holder = (ViewHolder) rowView.getTag();
holder.tvName.setText(items.get(position).getName());
holder.tvDescription.setText(items.get(position).getDescription());
return rowView;
}
}
导入android.content.Context;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.ArrayAdapter;
导入android.widget.TextView;
导入java.util.List;
公共类ListItemAdapter扩展了ArrayAdapter{
私人最终语境;
私人清单项目;
公共ListItemAdapter(上下文、int资源、列表值){
super(上下文、R.layout.list_项、值);
this.context=上下文;
此项=值;
}
私有静态类视图持有者{
文本视图tvName;
文本视图描述;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
视图行视图=转换视图;
if(rowView==null){
LayoutFlater充气器=(LayoutFlater)上下文
.getSystemService(上下文布局\充气机\服务);
rowView=充气机。充气(R.layout.list_项,父项,false);
ViewHolder ViewHolder=新ViewHolder();
viewholder.tvName=(TextView)rowView.findViewById(R.id.tvName);
viewholder.tvDescription=(TextView)rowView.findviewbyd(R.id.tvDescription);
rowView.setTag(viewholder);
}
ViewHolder=(ViewHolder)rowView.getTag();
holder.tvName.setText(items.get(position.getName());
holder.tvDescription.setText(items.get(position.getDescription());
返回行视图;
}
}
第二段:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class SecondFragment extends Fragment {
private final static String TAG = "SecondFragment";
private List<ListItem> items = new ArrayList<>();
private ListView lv;
private ListItemAdapter adapter;
public SecondFragment() {}
public static SecondFragment newInstance() {
Bundle args = new Bundle();
secondFragment.setArguments(args);
return secondFragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
items.add(new ListItem(1, "Willem", "Willemkeurige beschrijving"));
items.add(new ListItem(2, "Jos", "De Klos"));
items.add(new ListItem(3, "Leo", "Pold"));
adapter = new ListItemAdapter(getActivity(), 0, items);
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_second, container, false);
lv = (ListView) v.findViewById(R.id.lvSecond);
lv.setAdapter(adapter);
return v;
}
public void receiver() {
items.add(new ListItem(4, "Willem2", "Willemkeurige beschrijving"));
items.add(new ListItem(5, "Jos2", "De Klos"));
items.add(new ListItem(6, "Leo", "Pold3"));
adapter.notifyDataSetChanged();
}
}
导入android.os.Bundle;
导入android.support.annotation.Nullable;
导入android.support.v4.app.Fragment;
导入android.util.Log;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.ListAdapter;
导入android.widget.ListView;
导入java.util.ArrayList;
导入java.util.List;
公共类SecondFragment扩展了片段{
私有最终静态字符串TAG=“SecondFragment”;
私有列表项=新的ArrayList();
私有ListView lv;
专用ListItemAdapter适配器;
public SecondFragment(){}
公共静态SecondFragment newInstance(){
Bundle args=新Bundle();
secondFragment.setArguments(args);
返回第二个片段;
}
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
添加(新列表项(1,“威廉”、“威廉·基里奇·贝什里金”);
增加(新的清单项目(2,“Jos”、“De Klos”);
增加(新的清单项目(3,“Leo”、“Pold”);
adapter=新的ListItemAdapter(getActivity(),0,items);
}
@凌驾
创建视图时的公共视图(LayoutFlater充气机、@Nullable ViewGroup容器、@Nullable Bundle savedInstanceState){
视图v=充气机。充气(R.layout.fragment_second,容器,假);
lv=(ListView)v.findViewById(R.id.lvSecond);
低压设置适配器(适配器);
返回v;
}
公共接管人(){
添加(新列表项(4,“Willem2”、“Willemkeurige beschrijving”);
增加(新的清单项目(5,“Jos2”、“De Klos”);
增加(新的清单项目(6,“Leo”、“Pold3”);
adapter.notifyDataSetChanged();
}
}
您可以尝试以下方法:
在MyActivity
中添加:
public class MyActivity extends FragmentActivity {
//...
private ListItemAdapter mAdapter;
public ListItemAdapter getAdapter(){
if (mAdapter==null){
mAdapter = new ListItemAdapter();
}
return mAdapter;
}
}
在片段中
可以使用以下方法获取适配器
:
((MyActivity)getActivity()).getAdapter();
通过这种方式,您可以“共享”您的
适配器
问题在于,在添加片段之前,您的调用接收器()已被删除。片段有自己的生命周期,因此不能保证调用了onCreate和onCreateView。这就是适配器为空的原因。要解决此问题,您可以执行以下操作:
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_second, container, false);
lv = (ListView) v.findViewById(R.id.lvSecond);
lv.setAdapter(adapter);
receiver();
return v;
}
public void receiver(){
//add your strings as normal
if(adapter != null){
adapter.notifyDataSetChanged();
}
}
好的,这是可行的,但它会立即执行receive(),并忽略该按钮,因此在需要时仍然无法刷新列表。当我尝试使用该按钮时,它仍然会崩溃。已经实现了该按钮以避免崩溃,但它不会更新我的列表。你用什么更新它?现在,看起来您正在使用与我的receive()方法完全相同的数据替换。我正在向列表中添加3项。是否有更好的方法可以让我不必接触main活动?稍后我将扩展该应用程序,并添加几个具有类似功能的片段。这意味着我必须在MainActivity中为它们中的每一个创建一个适配器,同时必须有一种避免这样做的方法,并且有更干净的代码。您可以创建一个扩展
FragmentActivity
的MyActivity
,而getAdapter
方法是唯一的添加。然后,您未来的所有活动都将扩展MyActivity
。