我一直在寻找一段时间的答案,但我找不到相同的情况,所以我会在这里试一试。
我目前正在创建一个包含Activity,2个片段和viewpager功能的应用。片段1有一个按钮,它将更新片段2上的列表(通常的方式,frag 1 - > activity - > frag 2),当它到达该方法并调用notifyDataSetChanged时,它会崩溃,因为适配器为null。显然适配器为null,填充listview的现有List为空(这不是一个大问题,因为它再次被填充,但我想保留原始项目。)
如何更新我的列表以及为什么我的适配器为空?
我的代码:
MainActivity
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;
}
}
SecondFragment:
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();
}
}
答案 0 :(得分:0)
你可以试试这个:
在MyActivity
添加:
public class MyActivity extends FragmentActivity {
//...
private ListItemAdapter mAdapter;
public ListItemAdapter getAdapter(){
if (mAdapter==null){
mAdapter = new ListItemAdapter();
}
return mAdapter;
}
}
在您的Fragment
中,您可以使用Adapter
获取
((MyActivity)getActivity()).getAdapter();
这样您就可以“分享”Adapter
。
答案 1 :(得分:0)
问题是在片段添加之前你的呼叫接收者()。该片段有自己的生命周期,因此无法保证已调用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();
}
}