如何将图像点击数据从 RecycleAdapter 传递到 Fragment 接口,我在 MainActivity 中使用它来显示数据
How to pass data on image click from RecycleAdapter to Fragment interface, which I used in MainActivity to show data
我正在尝试将数据从 RecycleAdapter class 的 onClick 方法存档到 Fragment Class 并且那个 fragement class 有我在 MainActivity 中使用的接口得到那个数据。我在 Fragment class 中创建了一个 onButtonPressed() 方法,我在 recycleadapter onclick 方法中调用它来获取数据。
但是当我点击任何图像时,它显示 NullPointerException 错误:
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)
这是我的代码
1) 主要 Activity class
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);
}
}
}
2) Fragment_main class
<* 更正后 *>************
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);
}
}
3) 回收适配器 class
public class RecyclerAdapter 扩展 RecyclerView.Adapter{
私有列表 resultsList=new ArrayList();
私有视图 rcView;
私有上下文上下文;
int 介词;
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);
}
}
}
更正后它再次显示 NullPointerException :
这是错误
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
两个class代码在这里:
片段class
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);
}
}
回收适配器class
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);
}
}
}
Fragment class 方法和 RecycleAdapter onclick 方法中再次出现 NullException。
I test it via toast. Data comes in Fragement but erro shows when it send
from fragment interface mListener to main Activity which called in
callback method.
@Override
public void onCurrentMovie(Results currentMovie) {
mListener.onFragmentInteraction(currentMovie);
}
和 RecycleAdapter class onclick 方法行
callback.onCurrentMovie(currentMovie);
错误logcat:
FATAL EXCEPTION: main
java.lang.NullPointerException
at com.santossingh.moviesinfoapp.Fragments.Fragment_main.onCurrentMovie(Fragment_main.java:173)
at com.santossingh.moviesinfoapp.Adapters.RecyclerAdapter$Holder.onClick(RecyclerAdapter.java:93)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
你做错的是:
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
个对象。
我正在尝试将数据从 RecycleAdapter class 的 onClick 方法存档到 Fragment Class 并且那个 fragement class 有我在 MainActivity 中使用的接口得到那个数据。我在 Fragment class 中创建了一个 onButtonPressed() 方法,我在 recycleadapter onclick 方法中调用它来获取数据。 但是当我点击任何图像时,它显示 NullPointerException 错误:
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)
这是我的代码 1) 主要 Activity class
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);
}
}
}
2) Fragment_main class <* 更正后 *>************
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);
}
}
3) 回收适配器 class
public class RecyclerAdapter 扩展 RecyclerView.Adapter{ 私有列表 resultsList=new ArrayList(); 私有视图 rcView; 私有上下文上下文; int 介词;
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);
}
}
} 更正后它再次显示 NullPointerException : 这是错误
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
两个class代码在这里: 片段class
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);
}
}
回收适配器class
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);
}
}
}
Fragment class 方法和 RecycleAdapter onclick 方法中再次出现 NullException。
I test it via toast. Data comes in Fragement but erro shows when it send from fragment interface mListener to main Activity which called in callback method.
@Override
public void onCurrentMovie(Results currentMovie) {
mListener.onFragmentInteraction(currentMovie);
}
和 RecycleAdapter class onclick 方法行
callback.onCurrentMovie(currentMovie);
错误logcat:
FATAL EXCEPTION: main
java.lang.NullPointerException
at com.santossingh.moviesinfoapp.Fragments.Fragment_main.onCurrentMovie(Fragment_main.java:173)
at com.santossingh.moviesinfoapp.Adapters.RecyclerAdapter$Holder.onClick(RecyclerAdapter.java:93)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
你做错的是:
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
个对象。