I try to flash an image view for 3 seconds and then return it to its original image. here is my code:
public class MainActivity extends AppCompatActivity
implements View.OnClickListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.imageView).setOnClickListener(this);
}
#Override
public void onClick(View v) {
ImageView pic = findViewById(R.id.imageView);
pic.setImageDrawable(getResources().getDrawable(R.drawable.devil));
//Wait Block
try
{
Thread.sleep(3000);
} catch (InterruptedException e){
Toast.makeText(this,"Problem occurred",Toast.LENGTH_LONG).show();
}
//End of wait block
pic.setImageResource(R.drawable.angel);
Toast.makeText(this,"Done",Toast.LENGTH_LONG).show();
}
So basically I want this code flow:
While the actual flow is the following :
Could you tell me the reason for this behavior as well as how to solve this?
i am a new comer in android development and facing some problems using firebase ui.
i wanted to retrieve data from my firebase database and show it on my recyclerView.
but i am constantly getting an error while making FirebaseRecyclerAdapter.
Here is My Code Sample:
public class UsersActivity extends AppCompatActivity {
private Toolbar userToolbar;
private RecyclerView usersList;
private DatabaseReference mUsersDatabase;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_users);
userToolbar = (Toolbar) findViewById(R.id.users_toolbar);
setSupportActionBar(userToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Users");
mUsersDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
usersList = (RecyclerView) findViewById(R.id.users_list);
usersList.setHasFixedSize(true);
usersList.setLayoutManager(new LinearLayoutManager(this));
}
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerAdapter<Users, UsersViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Users, UsersViewHolder>(
Users.class,
R.layout.single_user_list_layout,
UsersViewHolder.class,
mUsersDatabase
) {
#Override
protected void onBindViewHolder(#NonNull UsersViewHolder holder, int position, #NonNull Users model) {
holder.setName(model.getName());
}
#NonNull
#Override
public UsersViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return null;
}
};
usersList.setAdapter(firebaseRecyclerAdapter);
}
public static class UsersViewHolder extends RecyclerView.ViewHolder
{
View mView;
public UsersViewHolder(#NonNull View itemView) {
super(itemView);
mView = itemView;
}
public void setName(String name)
{
TextView userNameView = (TextView) mView.findViewById(R.id.single_user_name);
userNameView.setText(name);
}
}
}
The Error i'm getting is this:
please help!!
Sorry wanted to comment but i ain't got enough points to do so.
Try this first, if it doesnt work try using FirebaseRecyclerOptions
(The latest version (3.x) of FirebaseUI implements a different method ofinitializing a FirebaseRecyclerAdapter than previous versions.)
Make your " firebaseRecyclerAdapter " variable global, so you would have something like this.
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Users, UsersViewHolder>(
Users.class,
R.layout.single_user_list_layout,
UsersViewHolder.class,
mUsersDatabase
)
I am having an issue with a NPE on a clickListener on a RecyclerView which is in a fragment. Initially it works fine with it displaying a toast message, but when I rotate the device and touch any icon I get:
java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.android.newswiz.OnItemClickListener.onItemClick(java.lang.String)' on a null object reference
at com.example.android.newswiz.Fragments.PublishersSlidePageFragment$PublishersAdapter$PublishersAdapterViewHolder$1.onClick(PublishersSlidePageFragment.java:86)
Here is my Fragment class. I have commented the part where there is the NPE in the logs:
package com.example.android.newswiz.Fragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.android.newswiz.OnItemClickListener;
import com.example.android.newswiz.R;
public class PublishersSlidePageFragment extends Fragment {
public OnItemClickListener listener;
public PublishersSlidePageFragment(){}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle
savedInstanceState) {
ViewGroup rootView = (ViewGroup)
inflater.inflate(R.layout.fragment_publishers_slide_page,
container, false);
RecyclerView mRecyclerView =
rootView.findViewById(R.id.recyclerView_publishers);
int numberOfColumns =
Integer.parseInt(getContext().getResources().getString(R.string.no_of_cols));
mRecyclerView.setLayoutManager(new GridLayoutManager(getContext(),
numberOfColumns));
mRecyclerView.setHasFixedSize(true);
PublishersAdapter mAdapter = new PublishersAdapter();
mRecyclerView.setAdapter(mAdapter);
return rootView;
}
public void setListener(OnItemClickListener onItemClickListener) {
this.listener = onItemClickListener;
}
public class PublishersAdapter extends RecyclerView.Adapter<PublishersAdapter.PublishersAdapterViewHolder>{
#NonNull
#Override
public PublishersAdapter.PublishersAdapterViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.publisher_item, parent, false);
return new PublishersAdapterViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull PublishersAdapter.PublishersAdapterViewHolder holder, int position) {
holder.mPublisherImageView.setImageResource(mThumbIds[position]);
holder.mPublisherTextView.setText(mPublishers[position]);
holder.bind(mPublishers[position], listener);
}
#Override
public int getItemCount() {
return mThumbIds.length;
}
public class PublishersAdapterViewHolder extends RecyclerView.ViewHolder {
private final ImageView mPublisherImageView;
private final TextView mPublisherTextView;
public PublishersAdapterViewHolder(View itemView) {
super(itemView);
mPublisherImageView = itemView.findViewById(R.id.publisher_icon);
mPublisherTextView = itemView.findViewById(R.id.publisher_desc);
}
public void bind(final String mPublisher, final OnItemClickListener clickListener) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
clickListener.onItemClick(mPublisher); //NPE on this line
}
});
}
}
}
// references to the images
private Integer[] mThumbIds = {
R.drawable.abc_news, R.drawable.abc_news_au,
R.drawable.aftenposten, R.drawable.aljazeera_english,
R.drawable.bbc, R.drawable.cbs_news,
R.drawable.cnn_news, R.drawable.entertainment_weekly,
R.drawable.espn, R.drawable.financial_post,
R.drawable.financial_times, R.drawable.fox_news,
R.drawable.fox_sports, R.drawable.ign,
R.drawable.independent, R.drawable.lequipe,
R.drawable.metro, R.drawable.msnbc,
R.drawable.mtvnews, R.drawable.nat_geo,
R.drawable.nbc_news, R.drawable.new_scientist,
R.drawable.new_york_magazine, R.drawable.talk_sport,
R.drawable.techradar, R.drawable.the_guardian,
R.drawable.the_nyt, R.drawable.wsj
};
private String[] mPublishers = {"ABC News", "ABC News (AU)", "Aftenposten", "AlJazeera (ENG)"
, "BBC", "CBS News", "CNN News", "Entertainment Weekly", "ESPN", "Financial Post",
"Financial Times", "Fox News", "Fox Sports", "IGN", "Independent", "L'Equipe",
"Metro", "MSNBC", "MTV News", "Nat. Geo.", "NBC News", "New Scientist",
"NY Magazine", "Talk Sport", "TechRadar", "The Guardian", "NYT",
"Wall Street Journal"};
}
The Fragment class and listener are initialized in the Main Activity:
public class MainActivity extends AppCompatActivity {
private ViewPager mPager;
private SectionsPageAdapter mSectionsPageAdapter;
private Context context;
private TabLayout tabLayout;
private OnItemClickListener publisherClickListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
// Login authentication code ....
//Set up the ViewPager and PagerAdapter
mSectionsPageAdapter = new
SectionsPageAdapter(getSupportFragmentManager());
mPager = findViewById(R.id.sources_container);
setupViewPager(mPager);
tabLayout = findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mPager);
}
//FIXME NPE on listener object if you rotate screen and touch icon
private void setupViewPager(ViewPager mPager) {
SectionsPageAdapter adapter = new SectionsPageAdapter(getSupportFragmentManager());
PublishersSlidePageFragment publishersSlidePageFragment = new PublishersSlidePageFragment();
publisherClickListener = new OnItemClickListener() {
#Override
public void onItemClick(String item) {
Toast.makeText(context, "You have selected " + item, Toast.LENGTH_SHORT).show();
}
};
publishersSlidePageFragment.setListener(publisherClickListener);
adapter.addFragment(publishersSlidePageFragment, "Publishers");
adapter.addFragment(new CategoriesSlidePageFragment(), "Categories");
adapter.addFragment(new CountriesSlidePageFragment(), "Countries");
mPager.setAdapter(adapter);
}
I find it very weird that it is fine to recreate the fragments when the screen is rotated but is unable to make a new clickListener to the fragment. I have searched StackOverflow and found Save interface (Listener) in onSaveInstanceState to be of use but I don't think in my situation it is good practice to save the listener. I want to make a new listener and just set it on the Recycler View within the fragment. I might be missing something trivial but can anyone advise?
I don't have enough rep to comment, so I'll provide what I believe could be the answer...
First, I noticed that there is no reference to the View "itemView" passed into the method "bind(final String mPublisher, final OnItemClickListener clickListener)" and I don't see it globally available. Not sure why it would run once and NPE after screen rotation though.
So, this points me to not saving the fragments instance. Something is being destroyed when you rotate your device, and if the log is correct, it's saying that is the variable mPublisher is being passed in as null.
mPublishers exists the first time the fragment is created, but looks like it's being destroyed / not recreated on an orientation change.
First thing I would try is setRetainInstance(true) to save the fragments instance across config changes. I have been setting it in onCreate(), but I see no reason you can't set it in onCreateView().
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
if (DEBUG) Log.i(TAG, "onCreate(Bundle)");
super.onCreate(savedInstanceState);
// retain this fragment across configuration changes
setRetainInstance(true);
}
If that doesn't do it automatically for you, save the publisher list when the fragment is being recreated. This is done in onSaveInstanceState() of your fragment.
#Override
public void onSaveInstanceState(#NonNull Bundle bundle) {
if (DEBUG) Log.i(TAG, "onSaveInstanceState(Bundle)");
// make sure to call the super method so that the states of our views are saved
super.onSaveInstanceState(bundle);
// save our own state variables
bundle.putStringArray("publishers", mPublishers);
}
Then you can restore them in your onCreateView() method.
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_publishers_slide_page, container, false);
RecyclerView mRecyclerView = rootView.findViewById(R.id.recyclerView_publishers);
int numberOfColumns = Integer.parseInt(getContext().getResources().getString(R.string.no_of_cols));
mRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), numberOfColumns));
mRecyclerView.setHasFixedSize(true);
PublishersAdapter mAdapter = new PublishersAdapter();
mRecyclerView.setAdapter(mAdapter);
// if we have a savedInstanceState, restore the Fragment
if (savedInstanceState != null) {
mPublishers = savedInstanceState.getStringArray("publishers");
}
return rootView;
}
You may have to do this for other variables as well, such as your mThumbIds array.
The solution was actually a simple fix - I actually needed to define an OnItemClickListener interface in the Fragment class. Then override the onAttach method to set the listener to the context. Previously I just made a separate interface.
So in the Fragment class:
public class PublishersSlidePageFragment extends Fragment {
private OnItemClickListener listener;
public PublishersSlidePageFragment(){}
public interface OnItemClickListener{
void onItemClick(String item);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
listener = (OnItemClickListener) context;
}
// ... rest of code
Then in the MainActivity, declare that you will implement the PublishersSlidePageFragment.OnItemClickListener:
public class MainActivity extends AppCompatActivity implements PublishersSlidePageFragment.OnItemClickListener {
Then that class needs to implement the listener method:
#Override
public void onItemClick(String item) {
Toast.makeText(context, "You have clicked " + item, Toast.LENGTH_SHORT).show();
}
I am using an MVC model where I initialize all the action listeners for the view in the controller. For example:
The view:
public void addStartDateListener(ChangeListener<Boolean>e){
startDate.focusedProperty().addListener(e);
}
public void addFinishDateListener(ChangeListener<Boolean>e){
finishDate.focusedProperty().addListener(e);
}
The controller:
this.theView.addStartDateListener(new startDateFocusListener());
this.theView.addFinishDateListener(new finishDateFocusListener());
class finishDateFocusListener implements ChangeListener<Boolean> {
#Override
public void changed(ObservableValue<? extends Boolean> arg0, Boolean oldPropertyValue, Boolean newPropertyValue)
{
if (newPropertyValue)
{
System.out.println("Finish date");
}
else
{
System.out.println("Finish date");
}
}
}
//focus listener to update the date whenever the focus is lost
class startDateFocusListener implements ChangeListener<Boolean> {
#Override
public void changed(ObservableValue<? extends Boolean> arg0, Boolean oldPropertyValue, Boolean newPropertyValue)
{
if (newPropertyValue)
{
System.out.println("start date");
}
else
{
System.out.println("start date");
}
}
As the stage(which is the view) appears I need for the application to wait till it gets closed and not allow the user to perform any other action on other stages. If however I use "showAndWait()" with "initModality(Modality.APPLICATION_MODAL);" The action listeners do not get added to the view, but if I use only "initModality(Modality.APPLICATION_MODAL);" it does not allow the user to perform any actions on other stages except the one and all the action listener are fully functional, but I still need to wait till the stage gets closed and only then continue further as the rest is depending on the output of the stage that is being created. So my question is how can I do it?
I have so far tried to use Task with "setOnSucced" and etc. However no luck. I am fairly new to the MVC concept as well.
I'm having the problem that for the following activity
public class MainActivity extends FragmentActivity implements UpdateActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tabbed_main_activity); <-- error here
I get the follwoing error: Cannot resolve method setContentView(int)
What am I doing wrong?
PS: I also cross checked with http://developer.android.com/training/basics/fragments/fragment-ui.html