如何将图像上的数据从RecycleAdapter传递到Fragment界面,我在MainActivity中使用它来显示数据

时间:2016-04-17 07:54:06

标签: android android-fragments nullpointerexception android-fragmentactivity recycler-adapter

我正在尝试将来自RecycleAdapter类的onClick方法的数据存档到Fragment Class,并且该fragement类具有我在MainActivity中用于获取该数据的接口。我在Fragment类中创建了一个onButtonPressed()方法,我在recycleadapter onclick方法中调用了get方法。 但是当我点击任何图像时,它会显示NullPointerException错误:

<div class="modal-content">
    <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title" id="myModalLabel">MASUKKAN SETORAN UNTUK = <b><?php echo $sr; ?></b> ~ <?php echo $flightnum; ?></h4>
    </div>
        <div class="modal-body">
            <table class="display" cellspacing="0" width="100%" id="paymentTable">
                <thead>
                    <th style="width: 1%;">NO</th>
                    <th style="width: 30%;">MATA UANG</th>
                    <th>RATE</th>
                    <th>SETORAN</th>
                    <th>TOTAL IDR</th>
                </thead>
                <tbody>
                <?php
                $i = 1;
                    while ($row = $result->fetch_array()) {
                        echo "<tr>";
                            echo "<td style='width: 1%; '>$row[curr_id]</td>";
                            echo "<td>$row[curr_code] - $row[curr_desc]</td>";
                            echo "<td><input type='hidden' value='$row[conv_rate]' id='convRate$i'>$row[conv_rate]</td>";
                            echo "<td><input type='text' onkeyup='processCurr($i);' id='inputCurr$i'/></td>";
                            echo "<td class='innertd'><div id='calculatedCurr$i' class='calculatedCurr'></div></td>";
                        echo "</tr>";
                        $i++;
                    }
                ?>
                </tbody>
            </table><br/>TOTAL = <div id='totalSumPayment'></div>
            <button class="btn btn-block btn-primary">SUBMIT <b><?php echo $sr; ?></b> ~ <?php echo $flightnum; ?> DATA</button>
        </div>
</div>

<script>
    $('#paymentTable').dataTable();
    function processCurr(param){    
        var inputcurr= $('#inputCurr'+param).val();
        var conversion = $('#convRate'+param).val();
        $('#calculatedCurr'+param).html(inputcurr * conversion);
        calculateSum();
    }

    function calculateSum(){
        var sum = 0;
        //iterate through each textboxes and add the values
        $(".calculatedCurr").each(function(key,value) {
            //add only if the value is number
            if (!isNaN(value) && value.length != 0) {
                sum += parseFloat(value);
                $(this).css("background-color", "#FEFFB0");
            }
            else if (value.length != 0){
                $(this).css("background-color", "blue");
            }
        });

            $("#totalSumPayment").html(sum);
    }
</script>

这是我的代码 1)主要活动类

04-17 03:24:56.376 6507-6545/com.santossingh.moviesinfoapp E/Surface: getSlotFromBufferLocked: unknown buffer: 0xf3d958e0
04-17 03:24:58.211 6507-6507/com.santossingh.moviesinfoapp E/AndroidRuntime: FATAL EXCEPTION: main
                                                                             Process: com.santossingh.moviesinfoapp, PID: 6507
                                                                             java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
                                                                                 at android.widget.Toast.<init>(Toast.java:102)
                                                                                 at android.widget.Toast.makeText(Toast.java:259)
                                                                                 at com.santossingh.moviesinfoapp.Fragments.Fragment_main.onButtonPressed(Fragment_main.java:176)
                                                                                 at com.santossingh.moviesinfoapp.Adapters.RecyclerAdapter$Holder.onClick(RecyclerAdapter.java:89)
                                                                                 at android.view.View.performClick(View.java:5198)
                                                                                 at android.view.View$PerformClick.run(View.java:21147)
                                                                                 at android.os.Handler.handleCallback(Handler.java:739)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                 at android.os.Looper.loop(Looper.java:148)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

2)Fragment_main类 &lt; *更正后*&gt; ************

public class MainActivity extends AppCompatActivity implements Fragment_main.OnFragmentInteractionListener{

    private Realm realm;
    private Results results;
    RecyclerAdapter recyclerAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(this).build();
        Realm.setDefaultConfiguration(realmConfiguration);

    }

    @Override
    public void onFragmentInteraction(Results currentMovie) {
        if (currentMovie==null){
            Toast.makeText(this,"Null",Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(this,"Hi ",Toast.LENGTH_SHORT).show();
        }
        DetailFragment detailFragment = (DetailFragment) getFragmentManager()
                .findFragmentById(R.id.Detail_container);

        if (detailFragment == null) {
            Toast.makeText(this,"single view",Toast.LENGTH_SHORT).show();

            Intent intent = new Intent(this, DetailActivity.class)
                .putExtra("movie_Id", currentMovie.getId())
                .putExtra("movie_Name", currentMovie.getTitle())
                .putExtra("poster_Path", currentMovie.getPoster_path())
                .putExtra("back_poster_Path", currentMovie.getBackdrop_path())
                .putExtra("release_Date", currentMovie.getRelease_date())
                .putExtra("users_Rating", currentMovie.getVote_average())
                .putExtra("overview", currentMovie.getOverview());
            startActivity(intent);

        } else {
            detailFragment.UpdateTabletUI(currentMovie);
        }
    }
}

3)RecycleAdapter类

公共类RecyclerAdapter扩展了RecyclerView.Adapter {     private List resultsList = new ArrayList();     私人查看rcView;     私有上下文;     int介词;

public class Fragment_main extends Fragment implements RecyclerAdapter.GetDataFromAdapter {

    @Bind(R.id.recyclerView) RecyclerView recyclerView;
    private static final String STATE_MOVIES = "state_movies";
    private View rootView = null;
    private ServiceManager serviceManager;
    private RecyclerAdapter recyclerAdapter;
    private MovieResponse movieResponse;
    private List<Results> resultsList;

    private Results results;
    private OnFragmentInteractionListener mListener;
    private RecyclerAdapter.GetDataFromAdapter getDataFromAdapter;

    public Fragment_main() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelableArrayList(STATE_MOVIES, (ArrayList<? extends Parcelable>) resultsList);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.High_rated:
                if(item.isChecked()){
                    item.setChecked(false);
                }else{
                    item.setChecked(true);
                    makeService("TOP");
                    return true;
                }
            case R.id.most_Popular:
                if(item.isChecked()){
                    item.setChecked(false);
                }else{
                    item.setChecked(true);
                    makeService("POPULAR");
                    return true;
                }
            case R.id.favoriteList:
                if(item.isChecked()){
                    item.setChecked(false);
                }else{
                    item.setChecked(true);
                    Intent intent=new Intent(getActivity(), FavoriteActivity.class);
                    startActivity(intent);
                    return true;
                }
        }
        return super.onOptionsItemSelected(item);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_main, container, false);

            ButterKnife.bind(this, rootView);
            resultsList=new ArrayList<Results>();
            configRecycleView();

            if (savedInstanceState==null){
                makeService("POPULAR");
            }else{
                resultsList=savedInstanceState.getParcelableArrayList(STATE_MOVIES);
                recyclerAdapter.addMovieList(resultsList);
            }
        return rootView;
    }

    private void makeService(String query){
        serviceManager = new ServiceManager();
        Call<MovieResponse> listCall;
            if (query=="TOP") {
                listCall= serviceManager.getJSONData().getTopMovies();
            }else{
                listCall= serviceManager.getJSONData().getPopMovies();
            }
            listCall.enqueue(new Callback<MovieResponse>() {
                @Override
                public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
                    if (response.isSuccessful()) {
                        Results[] results = response.body().getResults();
                        resultsList = new ArrayList<Results>(Arrays.asList(results));
                        recyclerAdapter.addMovieList(resultsList);
                        Toast.makeText(getActivity(), "Data Fatch", Toast.LENGTH_SHORT).show();
                    }
                }

                @Override
                public void onFailure(Call<MovieResponse> call, Throwable t) {
                    Toast.makeText(getActivity(), t.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
    }

    private void configRecycleView() {
       recyclerView.setHasFixedSize(true);
       recyclerView.setRecycledViewPool(new RecyclerView.RecycledViewPool());
       recyclerView.setLayoutManager(new GridLayoutManager(getActivity(),
               2));
       recyclerAdapter = new RecyclerAdapter(getActivity(),getDataFromAdapter
       );
       recyclerView.setAdapter(recyclerAdapter);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    @Override
    public void onCurrentMovie(Results currentMovie) {
        mListener.onFragmentInteraction(currentMovie);
    }

    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        public void onFragmentInteraction(Results result);
    }

}

}  更正后,它再次显示NullPointerException: 这是错误

GetDataFromAdapter callback;
private Results currentMovie;

public interface GetDataFromAdapter{
    void onCurrentMovie(Results currentMovie);
}

public RecyclerAdapter(Context context, GetDataFromAdapter callback) {
    this.context=context;
    this.callback = callback;
}

@Override
// create View object and pass it on Holder class constructor
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
    rcView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_image_fragment, parent, false);
    return new Holder(rcView);
}

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

public void addMovieList(List<Results> movie){
    resultsList=movie;
    notifyDataSetChanged();
}

@Override
public void onBindViewHolder(Holder holder, int position) {
    Results currentMovie = resultsList.get(position);
    Picasso.with(holder.imageView.getContext())
            .load(Constant.HTTP.IMAGE_BASE_URL + currentMovie.getPoster_path())
            .resize(240, 330)
            .placeholder(R.drawable.placeholder)
            .error(R.drawable.error)
            .into(holder.imageView);

    // animation part ----------------
    if (position>preposition){
        AnimationUtil.animate(holder, true);
    }else {
        AnimationUtil.animate(holder,false);
    }
    preposition=position;
}

public class Holder extends RecyclerView.ViewHolder implements View.OnClickListener{
    private ImageView imageView;

    public Holder(View itemView) {
        super(itemView);
        itemView.setOnClickListener(this);
        imageView=(ImageView)itemView.findViewById(R.id.imageView);
    }

    @Override
    public void onClick(View v) {
        int position = getAdapterPosition();
        currentMovie=resultsList.get(position);
        Toast.makeText(v.getContext(),currentMovie.getTitle(),Toast.LENGTH_SHORT).show();
        callback.onCurrentMovie(currentMovie);
    }
}

更正后,单个错误显示,图像未在模拟器中显示,这是模拟器的图片:

enter image description here

04-17 04:19:21.832 7118-7147/com.santossingh.moviesinfoapp E/Surface: getSlotFromBufferLocked: unknown buffer: 0xdefa22a0
04-17 04:19:22.633 7118-7118/com.santossingh.moviesinfoapp E/AndroidRuntime: FATAL EXCEPTION: main
                                                                             Process: com.santossingh.moviesinfoapp, PID: 7118
                                                                             java.lang.NullPointerException: Attempt to invoke interface method 'void com.santossingh.moviesinfoapp.Adapters.RecyclerAdapter$GetDataFromAdapter.onCurrentMovie(com.santossingh.moviesinfoapp.DB.Models.Results)' on a null object reference
                                                                                 at com.santossingh.moviesinfoapp.Adapters.RecyclerAdapter$Holder.onClick(RecyclerAdapter.java:92)
                                                                                 at android.view.View.performClick(View.java:5198)
                                                                                 at android.view.View$PerformClick.run(View.java:21147)
                                                                                 at android.os.Handler.handleCallback(Handler.java:739)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                 at android.os.Looper.loop(Looper.java:148)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

这两个类代码在这里: 片段类

04-17 04:54:16.961 23492-23520/com.santossingh.moviesinfoapp E/Surface: getSlotFromBufferLocked: unknown buffer: 0xeb08a7e0

RecycleAdapter类

public class Fragment_main extends Fragment implements RecyclerAdapter.GetDataFromAdapter {

    @Bind(R.id.recyclerView) RecyclerView recyclerView;
    private static final String STATE_MOVIES = "state_movies";
    private View rootView = null;
    private ServiceManager serviceManager;
    private RecyclerAdapter recyclerAdapter;
    private MovieResponse movieResponse;
    private List<Results> resultsList;

    private Results results;
    private OnFragmentInteractionListener mListener;
    private RecyclerAdapter.GetDataFromAdapter getDataFromAdapter;

    public Fragment_main() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelableArrayList(STATE_MOVIES, (ArrayList<? extends Parcelable>) resultsList);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.High_rated:
                if(item.isChecked()){
                    item.setChecked(false);
                }else{
                    item.setChecked(true);
                    makeService("TOP");
                    return true;
                }
            case R.id.most_Popular:
                if(item.isChecked()){
                    item.setChecked(false);
                }else{
                    item.setChecked(true);
                    makeService("POPULAR");
                    return true;
                }
            case R.id.favoriteList:
                if(item.isChecked()){
                    item.setChecked(false);
                }else{
                    item.setChecked(true);
                    Intent intent=new Intent(getActivity(), FavoriteActivity.class);
                    startActivity(intent);
                    return true;
                }
        }
        return super.onOptionsItemSelected(item);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_main, container, false);

            ButterKnife.bind(this, rootView);
            resultsList=new ArrayList<Results>();
            configRecycleView();

            if (savedInstanceState==null){
                makeService("POPULAR");
            }else{
                resultsList=savedInstanceState.getParcelableArrayList(STATE_MOVIES);
                recyclerAdapter.addMovieList(resultsList);
            }
        return rootView;
    }

    private void makeService(String query){
        serviceManager = new ServiceManager();
        Call<MovieResponse> listCall;
            if (query=="TOP") {
                listCall= serviceManager.getJSONData().getTopMovies();
            }else{
                listCall= serviceManager.getJSONData().getPopMovies();
            }
            listCall.enqueue(new Callback<MovieResponse>() {
                @Override
                public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
                    if (response.isSuccessful()) {
                        Results[] results = response.body().getResults();
                        resultsList = new ArrayList<Results>(Arrays.asList(results));
                        recyclerAdapter.addMovieList(resultsList);
                        Toast.makeText(getActivity(), "Data Fatch", Toast.LENGTH_SHORT).show();
                    }
                }

                @Override
                public void onFailure(Call<MovieResponse> call, Throwable t) {
                    Toast.makeText(getActivity(), t.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
    }

    private void configRecycleView() {
       recyclerView.setHasFixedSize(true);
       recyclerView.setRecycledViewPool(new RecyclerView.RecycledViewPool());
       recyclerView.setLayoutManager(new GridLayoutManager(getActivity(),
               2));
       recyclerAdapter = new RecyclerAdapter(getActivity(),getDataFromAdapter);
       recyclerView.setAdapter(recyclerAdapter);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    @Override
    public void onCurrentMovie(Results currentMovie) {
        mListener.onFragmentInteraction(currentMovie);
    }

    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        public void onFragmentInteraction(Results result);
    }

}

在Fragment类方法和RecycleAdapter onclick方法中再次使用NullException。

  

我通过吐司测试。数据出现在Fragement中,但erro会在发送时显示   从片段接口mListener到调用的主Activity   回调方法。

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.Holder>{
    private List<Results> resultsList=new ArrayList<Results>();
    private View rcView;
    private Context context;
    int preposition;

    GetDataFromAdapter callback;
    private Results currentMovie;

    public interface GetDataFromAdapter{
        void onCurrentMovie(Results currentMovie);
    }

    public RecyclerAdapter(Context context, GetDataFromAdapter callback) {
        this.context=context;
        this.callback = callback;
    }

    @Override
    // create View object and pass it on Holder class constructor
    public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
        rcView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.list_image_fragment, parent, false);
        return new Holder(rcView, callback);
    }

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

    public void addMovieList(List<Results> movie){
        resultsList=movie;
        notifyDataSetChanged();
    }

    @Override
    public void onBindViewHolder(Holder holder, int position) {
        Results currentMovie = resultsList.get(position);
        Picasso.with(holder.imageView.getContext())
                .load(Constant.HTTP.IMAGE_BASE_URL + currentMovie.getPoster_path())
                .resize(240, 330)
                .placeholder(R.drawable.placeholder)
                .error(R.drawable.error)
                .into(holder.imageView);

        // animation part ----------------
        if (position>preposition){
            AnimationUtil.animate(holder, true);
        }else {
            AnimationUtil.animate(holder,false);
        }
        preposition=position;
    }

    public class Holder extends RecyclerView.ViewHolder implements View.OnClickListener{
        private ImageView imageView;
        private GetDataFromAdapter callback;

        public Holder(View itemView, GetDataFromAdapter callback) {
            super(itemView);
            itemView.setOnClickListener(this);
            this.callback=callback;
            imageView=(ImageView)itemView.findViewById(R.id.imageView);
        }

        @Override
        public void onClick(View v) {
            int position = getAdapterPosition();
            currentMovie=resultsList.get(position);
            Toast.makeText(v.getContext(),currentMovie.getTitle(),Toast.LENGTH_SHORT).show();
            callback.onCurrentMovie(currentMovie);
        }
    }

}

和RecycleAdapter类onclick方法行

@Override
    public void onCurrentMovie(Results currentMovie) {
        mListener.onFragmentInteraction(currentMovie);
    }

错误logcat:

   callback.onCurrentMovie(currentMovie);

1 个答案:

答案 0 :(得分:1)

你做错了是:

fragment_main=new Fragment_main();
fragment_main.onButtonPressed(currentMovie);

制作fragment的新实例。该实例如何引用正在显示的实例?

您可以通过如下所述的界面获取数据:

在适配器中定义interface

public interface GetDataFromAdapter{
    void onCurrentMovie(Results currentMovie);
}

fragment中实现并覆盖接口方法:

public class Fragment_main extends Fragment implements RecyclerAdapter.GetDataFromAdapter{
}

并创建如下的适配器实例:

recyclerAdapter = new RecyclerAdapter(getActivity(), Fragment_main.this);
recyclerView.setAdapter(recyclerAdapter);

现在更改适配器的构造函数,如下所示:

GetDataFromAdapter callback;
private Results currentMovie;

public RecyclerAdapter(Context context, GetDataFromAdapter callback) {
    this.context=context;
    this.callback = callback;
}

现在,由于您要从ViewHolder传递数据,因此您必须将callback引用传递给它。

public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
   rcView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.list_image_fragment, parent, false);
   return new Holder(rcView, callback);
}

因此Holder的构造函数就像:

private ImageView imageView;
private GetDataFromAdapter callback;

public Holder(View itemView, GetDataFromAdapter callback) {
    super(itemView);
    this.callback = callback;
    itemView.setOnClickListener(this);
    imageView=(ImageView)itemView.findViewById(R.id.imageView);
}

将数据发送到这样的片段:

@Override
public void onClick(View v) {
    int position = getAdapterPosition();
    currentMovie=resultsList.get(position);

    callback.onCurrentMovie(currentMovie);
}

片段中的覆盖方法将接收currentMovie个对象。