RecyclerView适配器未在片段

时间:2016-04-15 02:06:57

标签: android android-fragments

所以我一直在使用RecyclerView,我已经在Activity中正常运行了;但是一旦我在片段中尝试它,它就不会更新UI。

MainActivity.java

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TextInputEditText;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

    public class MainActivity extends AppCompatActivity implements AddItemDialog.OnItemAddedListener {

    private FloatingActionButton fab;

    private FragmentManager manager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RecyclerFragment rvf = new RecyclerFragment();
        manager = getSupportFragmentManager();
        FragmentTransaction ft = manager.beginTransaction();
        ft.add(R.id.frag_container, rvf, "TAG");
        ft.commit();

        fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            AddItemDialog dialog = new AddItemDialog();
                dialog.show(getSupportFragmentManager(), "DIALOG");
            }
        });
        fab.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                Intent intent = new Intent(getBaseContext(), _3DTouch.class);
                startActivity(intent);
                return true;
            }
        });

        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
        }

        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 2);
        }
    }

    @Override
    public void onDialogPositiveClick(String entry) {
        RecyclerFragment rvfFrag = (RecyclerFragment) getSupportFragmentManager().findFragmentByTag("TAG");
        rvfFrag.refreshData(entry);
    }

    @Override
    public void onDialogNegativeClick() {}
}

FragmentAdapter.java

import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by jfelt on 15/04/2016.
 */
public class FragmentAdapter extends RecyclerView.Adapter<FragmentAdapter.ViewHolder> {

    private List<TestEntry> testEntries = Collections.emptyList();

    public static class ViewHolder extends RecyclerView.ViewHolder {

        TextView textView;

        ViewHolder(View itemView) {
            super(itemView);
            textView = (TextView) itemView.findViewById(R.id.rv_item);
        }
    }

    @Override
    public int getItemCount() {
        return testEntries.size();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup vg, int i) {
        View v = LayoutInflater.from(vg.getContext()).inflate(R.layout.entry, vg, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder vh, int i) {
        vh.textView.setText(testEntries.get(i).getItem());
    }
}

RecyclerFragment.java

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by jfelt on 14/04/2016.
 */
public class RecyclerFragment extends Fragment {

    List<TestEntry> testEntries = new ArrayList<>();

    private RecyclerView recyclerView;
    private RecyclerView.Adapter adapter;
    private RecyclerView.LayoutManager manager;

    public RecyclerFragment() {}

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle args = getArguments();
        if (args != null) {
            Log.d("RecyclerFragment", String.valueOf(args));
        }
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        recyclerView = (RecyclerView) view.findViewById(R.id.recycler);
        manager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(manager);
        adapter = new FragmentAdapter();
        recyclerView.setAdapter(adapter);
    }

    @Override
    public View onCreateView(LayoutInflater inf, ViewGroup vg, Bundle savedInstanceState) {
        View rv = inf.inflate(R.layout.rv_layout, null);
        return rv;
    }

    public void refreshData(String entry) {
        Log.d("TAG", entry);
        testEntries.add(new TestEntry(entry));
        Log.d("TAG", String.valueOf(testEntries));
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                adapter.notifyItemInserted(testEntries.size() - 1);
            }
        });
    }
}

日志记录显示refreshData接收来自Dialog侦听器的输入。问题似乎在于调用adapter.notifyItemInserted,因为它似乎没有被正确调用。我可能错过了一些显而易见的东西,但我已经盯着这段代码好几个小时了,只是想不出来。非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

如何将Fragment中的testEntries引用到Adapter内的testEntries?我认为问题是你不要告诉你适配器更新的数据。我建议在Adapter中创建一个函数来添加条目,然后添加notifyItemsInserted。

FragmentAdapter内部:

public void addItem(String entry){
    this.testEntries.add(entry);
    notifyItemInserted(testEntries.size() - 1);
} 

内部碎片:

((FragmentAdapter) getAdapter()).addItem(entry);

答案 1 :(得分:0)

FragmentAdapterRecyclerFragment我们引用不同的列表,因此当您将项目添加到其中时,它不会被添加到另一个项目中。

一个适用于您当前代码结构的选项是向[{1}}添加构造函数,该构造函数需要FragmentAdapter,以便它们都具有相同的List引用:

List

然后在您的片段的public FragmentAdapter(List<TestEntry testEntries) { this.testEntries = testEntries; } 中将其列表作为参数传递给onViewCreated()构造函数。

FragmentAdapter

此外,您不需要adapter = new FragmentAdapter(testEntries); ,因为此时您已经在UI线程上。您只需拨打电话即可添加该项目。

getActivity().runOnUiThread