Android - 在片段之间进行通信,适配器为空

时间:2015-03-16 08:57:56

标签: android android-fragments android-viewpager notifydatasetchanged

我一直在寻找一段时间的答案,但我找不到相同的情况,所以我会在这里试一试。

我目前正在创建一个包含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();
    }
}

2 个答案:

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