Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android-在片段之间通信,适配器为空_Android_Android Fragments_Android Viewpager_Notifydatasetchanged - Fatal编程技术网

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

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的现有列表是空的(这不是什么大问题,因为它会再次被填充,但我希望保留原始项) 如何更新我的列表以及为什

我已经寻找了一段时间的答案,但我还没有找到相同的情况,所以我将尝试在这里询问

我目前正在创建一个带有活动、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