I got an error with notifyDataSetChanged() on RecyclerView when I press back button. This is the code:
MainActivity.java
class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
public List<Article> articleList;
public RecyclerView recyclerView;
public RecyclerViewAdapter adapter;
ArrayList<String> my_list = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
initData();
adapter = new RecyclerViewAdapter(articleList, MainActivity.this);
recyclerView.setAdapter(adapter);
}
private void initData() {
articleList = new ArrayList<>();
queryArticle();
}
public void saveArticle(String title, String desc) {
//ab is a instance for class Article_Bmob
ab.setTitle(title);
ab.setDesc(desc);
ab.save(new SaveListener<String>() {
#Override
public void done(String s, BmobException e) {
if(e == null) {
} else {
e.printStackTrace();
}
}
});
}
}
WriteArticle.java (Error File)
public class WriteArticle extends AppCompatActivity {
MainActivity mainActivity;
private String art_title, art_desc;
private EditText edt_title, edt_desc;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.write_article);
edt_title = (EditText) findViewById(R.id.w_art_title);
edt_desc = (EditText) findViewById(R.id.w_art_desc);
Button btn_send = (Button) findViewById(R.id.send_article);
mainActivity = new MainActivity();
btn_send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
art_title = edt_title.getText().toString();
art_desc = edt_desc.getText().toString();
if (art_title.isEmpty()) {
Snackbar.make(view, "R.String.xxx", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
} else if (art_desc.isEmpty()) {
Snackbar.make(view, "R.String.xxx", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
} else {
mainActivity.saveArticle(art_title, art_desc);
mainActivity.adapter.notifyDataSetChanged();
finish();
}
}
});
}
And the error:
java.lang.NullPointerException: Attempt to invoke virtual method
'void com.myapplication.RecyclerViewAdapter.notifyDataSetChanged()' on a null object reference
at com.myapplication.WriteArticle$1.onClick(WriteArticle.java:52)
How can I solve this?
In your MainActivity
public static MainActivity mactivity;
public static MainActivity getinstance(){
return mactivity;
}
In your WriteArticle activity
MainActivity mainActivity;
And use it as
mainActivity.getinstance.saveArticle(art_title, art_desc);
mainActivity.getinstance.adapter.notifyDataSetChanged();
Related
How to implement like button hitting count in RecyclerView. I have already created a like button and counter TextView with this code but when I hit the like button the application crashes. This is my code, what's wrong? I am using toggle button for like option and a TextView for counting like hitting.
This is my viewholder
public class WritingsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView MainTitle;
public ImageView Mainimage;
public ImageView Profimage;
public TextView ProfName;
public TextView txv;
public ToggleButton liketglbtn;
public TextView MainDesc, Idvkanme;
private ItemClickListner itemClickListner;
public void setItemClickListner(ItemClickListner itemClickListner) {
this.itemClickListner = itemClickListner;
}
public WritingsViewHolder(View itemView) {
super(itemView);
MainTitle = (TextView)itemView.findViewById(R.id.RTitle);
Mainimage = (ImageView)itemView.findViewById(R.id.rImageView);
Profimage = (ImageView)itemView.findViewById(R.id.Profile_Image);
ProfName = (TextView)itemView.findViewById(R.id.Prof_Name);
MainDesc = (TextView)itemView.findViewById(R.id.rDescriptionTv);
Idvkanme = (TextView)itemView.findViewById(R.id.Idavaka_Name);
txv = (TextView)itemView.findViewById(R.id.tx);
liketglbtn = (ToggleButton) itemView.findViewById(R.id.likeToggleBtn);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
itemClickListner.onClick(v,getAdapterPosition(),false);
}
}
This is my activity
public class WritingsActivity extends AppCompatActivity {
RecyclerView recyclerView;
FirebaseRecyclerOptions<IdavakaModel> options;
FirebaseRecyclerAdapter<IdavakaModel, WritingsViewHolder> adapter;
DatabaseReference MCC;
String categoryId = "";
RecyclerView.LayoutManager layoutManager;
TextView smsCountText;
int pendingSMSCount = 10;
static Button notifCount;
static int mNotifCount = 0;
Button FBcard, YoutubeCard;
private static final String APP_ID = "ca-app-pub-8867939169855032~9998384849";
Button mSaveBtn, mShareBtn;
private long backPressedTime;
private Toast backToast;
private int mCounter = 0;
ToggleButton btn;
TextView txv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_writings);
FBcard = (Button) findViewById(R.id.button1);
FBcard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent toy = new Intent(WritingsActivity.this, IdavakaNewsUploadActivity.class);
startActivity(toy);
WritingsActivity.this.finish();
}
});
MobileAds.initialize(this,APP_ID);
AdView adView = (AdView) findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
//Bottom Navigation Bar
final BottomNavigationView bottomNavigationView = (BottomNavigationView)findViewById(R.id.botmnavigation);
bottomNavigationView.setSelectedItemId(R.id.action_privacy);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.myhome:
startActivity(new Intent(getApplicationContext(),MainActivity.class));
overridePendingTransition(0,0);
return true;
case R.id.action_notification:
startActivity(new Intent(getApplicationContext(),ChristianNewsMainActivity.class));
overridePendingTransition(0,0);
return true;
case R.id.action_privacy:
return true;
}
return false;
}
});
MCC= FirebaseDatabase.getInstance().getReference().child("Writings");
recyclerView = (RecyclerView) findViewById(R.id.readingroom_recyclerView);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
LoadData(categoryId);
}
private void LoadData(String categoryId) {
options = new FirebaseRecyclerOptions.Builder<IdavakaModel>().setQuery(MCC,IdavakaModel.class).build();
adapter = new FirebaseRecyclerAdapter<IdavakaModel, WritingsViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull WritingsViewHolder writingsViewHolder, int i, #NonNull IdavakaModel idavakaModel) {
writingsViewHolder.MainTitle.setText(idavakaModel.getTitle());
writingsViewHolder.MainDesc.setText(idavakaModel.getDesc());
writingsViewHolder.ProfName.setText(idavakaModel.getProfname());
writingsViewHolder.Idvkanme.setText(idavakaModel.getIdavakaname());
Picasso.get().load(idavakaModel.getPostimage())
.into(writingsViewHolder.Mainimage);
Picasso.get().load(idavakaModel.getProfimage())
.into(writingsViewHolder.Profimage);
writingsViewHolder.setItemClickListner(new ItemClickListner() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Intent detailsIntent = new Intent(WritingsActivity.this, IdavakaDetailActivity.class);
detailsIntent.putExtra("CategoryId", adapter.getRef(position).getKey());
startActivity(detailsIntent);
}
});
writingsViewHolder.liketglbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCounter++;
txv.setText(Integer.toString(mCounter));
}
});
}
#NonNull
#Override
public WritingsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.writngs_items, parent, false);
return new WritingsViewHolder(v);
}
};
adapter.startListening();
recyclerView.setAdapter(adapter);
}
#Override
public void onBackPressed() {
if (backPressedTime + 2000 > System.currentTimeMillis()) {
backToast.cancel();
super.onBackPressed();
WritingsActivity.this.finish();
return;
} else {
backToast = Toast.makeText(getBaseContext(), "See You Soon", Toast.LENGTH_SHORT);
backToast.show();
}
backPressedTime = System.currentTimeMillis();
WritingsActivity.this.finish();
}
public void onCustomToggleClick (View view) {
Toast.makeText(this, "Liked",Toast.LENGTH_SHORT).show();
}
}
You are getting NullPointerException because the TextView you are using is in Activity named txv where you are setting counter. But the problem is you have declared TextView in Activity but have not initialized anywhere in the Activity. You MUST initialize that variable via findViewbyId method before setting values.
Furthermore, you have initialized txv TextView and accessing on Activity that is why you are getting NLP. TextView is a part of Activity layout which you have not Initialized. On the hand you have initialized txv in Adapter which is of no use.
i'm from indonesia, i want to refresh a fragment after i insert a data to it.. i have try many times to refresh a fragment. but it can't work.
please help me..
here's my code..
class MainActivity
public class MainActivity extends FragmentActivity {
public MainActivity() {
}
DatabaseReference dataBaseref;
StorageReference strRef;
TextView logout;
TabLayout tabLayout;
ViewPager viewPager;
ViewPagerAdapter viewAdapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dataBaseref = FirebaseDatabase.getInstance().getReference();
strRef = FirebaseStorage.getInstance().getReference();
tabLayout = findViewById(R.id.tab_layout_isi_menu);
viewPager = findViewById(R.id.view_pager_isi_menu);
logout = findViewById(R.id.text_logout);
viewAdapter = new ViewPagerAdapter(getSupportFragmentManager(), MainActivity.this);
viewAdapter.addFragment(new isi_list_beli(), "Beli");
viewAdapter.addFragment(new isi_list_cek(), "Cek Data");
viewPager.setAdapter(viewAdapter);
tabLayout.setupWithViewPager(viewPager);
logout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
logOut();
}
});
}
private void logOut() {
AuthUI.getInstance()
.signOut(MainActivity.this)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
startActivity(new Intent(MainActivity.this, LoginActivity.class));
finish();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, "" + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
#Override
protected void onResume() {
super.onResume();
}
public void onBackPressed() {
super.finish();
}
}
class isi_list_cek
public class isi_list_cek extends Fragment {
private ListView listView;
public AdapterListCek adapterListCek = null;
private ArrayList<Cek> cekArrayList;
Cursor cursor;
View view;
FloatingActionButton fab;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
adapterListCek = new AdapterListCek(getContext(), R.layout.item_in_list_barang, cekArrayList);
adapterListCek.notifyDataSetChanged();
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #NonNull Bundle savedInstanceState) {
view = inflater.inflate(R.layout.list_barang, container, false);
listView = view.findViewById(R.id.list_item_barang);
fab = view.findViewById(R.id.tambah_barang);
cekArrayList = new ArrayList<>();
adapterListCek = new AdapterListCek(getContext(), R.layout.item_in_list_barang, cekArrayList);
listView.setAdapter(adapterListCek);
cursor = fragment_input_data.sqlHelper.getData("SELECT * FROM CEK");
if(cursor.moveToFirst()){
cekArrayList.clear();
do{
int id = cursor.getInt(0);
String kode = cursor.getString(1);
String nama = cursor.getString(2);
String jumlah = cursor.getString(3);
String harga = cursor.getString(4);
byte[] gambar = cursor.getBlob(5);
cekArrayList.add(new Cek(id, kode, nama, harga, jumlah, gambar));
}while (cursor.moveToNext());
fragment_input_data.sqlHelper.close();
}
adapterListCek.notifyDataSetChanged();
listView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
return false;
}
});
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(getContext(), fragment_input_data.class));
}
});
return view;
}
#Override
public void onResume() {
super.onResume();
}
}
class ViewPagerAdapter
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private Map<Integer, String> mFragmentTags;
private FragmentManager mFragmentManager;
private Context mContext;
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentListTitle = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm, Context mContext) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public int getCount() {
return fragmentListTitle.size();
//return 2;
}
#NonNull
#Override
public CharSequence getPageTitle(int position) {
return fragmentListTitle.get(position);
}
public void addFragment (Fragment fragment, String string){
fragmentList.add(fragment);
fragmentListTitle.add(string);
}
}
i expect when i insert some data, fragment will automatically update it's view.
call a function as: just send the new instance of present fragment that you want to recreate
replaceFragment(new YourPresentFragment());
the function can be as below:
private void replaceFragment(Fragment fragment) {
String fragmentTag = fragment.getClass().getName();
FragmentManager manager = getFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.fragments, fragment, fragmentTag);
ft.addToBackStack("fragments");
ft.commit();
}
this should do the job
I am unable to get my Message class in which I set my getters and setters to use in Main Activity. My coding is showing error on getContent() in onStart() void. Below is the code of Main Activity:
package com.example.tejindersingh.chatapplication;
public class MainActivity extends AppCompatActivity {
private EditText editMessage;
private DatabaseReference mDatabase;
private RecyclerView mMessageList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editMessage = (EditText) findViewById(R.id.editMessageE);
mDatabase = FirebaseDatabase.getInstance().getReference().child("Messages");
mMessageList = (RecyclerView) findViewById(R.id.messageRec);
mMessageList.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setStackFromEnd(true);
mMessageList.setLayoutManager(linearLayoutManager);
MainActivity mActivity= new MainActivity();
}
public void sendButtonClicked(View view){
final String messageValue = editMessage.getText().toString().trim();
if(!TextUtils.isEmpty(messageValue)){
final DatabaseReference newPost = mDatabase.push();
newPost.child("Content").setValue(messageValue);
}
}
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerAdapter <Message,MessageViewHolder> FBRA = new FirebaseRecyclerAdapter<Message, MessageViewHolder>(
Message.class,
R.layout.singlemessagelayout,
MessageViewHolder.class,
mDatabase
) {
#Override
protected void populateViewHolder(MessageViewHolder viewHolder, Message model, int position) {
viewHolder.setContent(model.getContent()); //Problem here
}
};
mMessageList.setAdapter(FBRA);
}
public static class MessageViewHolder extends RecyclerView.ViewHolder{
View mView;
public MessageViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setContent(String content){
TextView message_content = (TextView) mView.findViewById(R.id.messageText);
message_content.setText(content);
}
}
}
This shows the code for the external Message class in which I set getter and setter.
When you are calling populateViewHolder method. the Message model parameter, has String content which is null. In order to change that you need to use the setContent method.
Try to do this:
#Override
protected void populateViewHolder(MessageViewHolder viewHolder, Message model, int position) {
model.setContent("Write Here Your Content"); //new line of code
viewHolder.setContent(model.getContent());
}
I'd like to be able to send an object from parsed JSON data displayed on a RecyclerView to a new activity on click. Below is the relevant code:
I've tried a few solutions but I don't get any results. I've been getting this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
at athena.sentineljs.com.athena.RVNewsAdapter$NewsViewHolder.onClick(RVNewsAdapter.java:55)
RVNewsAdapter:
public class RVNewsAdapter extends RecyclerView.Adapter<RVNewsAdapter.NewsViewHolder> {
public static final String KEY_LINK = "link";
public static class NewsViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
private static final String TAG = "Hello";
CardView cv;
TextView date;
TextView link;
TextView title;
TextView today;
List<News> news;
public NewsViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.cv);
date = (TextView) itemView.findViewById(R.id.date);
link = (TextView) itemView.findViewById(R.id.link);
title = (TextView) itemView.findViewById(R.id.heading);
today = (TextView) itemView.findViewById(R.id.today);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Context context = view.getContext();
Intent intent;
intent = new Intent(context, Details.class);
intent.putExtra("LINK", news.toString());
context.startActivity(intent);
}
}
List<News> news;
RVNewsAdapter(List<News> news) {
this.news = news;
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public RVNewsAdapter.NewsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.itemnewsfeed, viewGroup, false);
NewsViewHolder nvh = new NewsViewHolder(v);
return nvh;
}
#Override
public void onBindViewHolder(NewsViewHolder newsViewHolder, int i) {
newsViewHolder.date.setText(news.get(i).date);
newsViewHolder.link.setText(news.get(i).link);
newsViewHolder.title.setText(news.get(i).title);
newsViewHolder.today.setText(news.get(i).today);
}
#Override
public int getItemCount() {
if (news != null) {
return news.size();
}
return 0;
}
}
Details activity:
public class Details extends AppCompatActivity {
private static final String TAG_LINK = "link";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Intent in = getIntent();
// Get JSON values from previous intent
String link = in.getStringExtra("link");
// Displaying all values on the screen
TextView lblLink = (TextView) findViewById(R.id.link);
lblLink.setText(link);
Log.d("Details", "Data not shown");
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
}
You should send the news object like this
#Override
public void onClick(View view) {
Context context = view.getContext();
Intent intent = new Intent(context, Details.class);
int clickPosition = getAdapterPosition(); // get position of clicked item
News newObject = news.get(clickPosition); // get clicked new object from news(news is an ArrayList)
intent.putExtra("LINK", newObject);
context.startActivity(intent);
}
Also for pass the object via Intent correctly please see this answer
Here is my login activity. The loginButtonListener declares a AsyncTask variable to work on the verify info on remote MySQL
public class LoginActivity extends AppCompatActivity implements AsyncResponse {
private EditText editText_email;
private EditText editText_password;
private Button button_login;
private Button button_register;
#Override
protected void onCreate(Bundle savedInstanceState) {
BackgroundWorker worker = new BackgroundWorker(LoginActivity.this);
loginButtonListener();
registerButtonListener();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
public void loginButtonListener(){
button_login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String type = "login";
String email = editText_email.getText().toString();
String password = editText_password.getText().toString();
BackgroundWorker worker = new BackgroundWorker(LoginActivity.this);
worker.execute(type, email, password);
}
});
}
}
Here is my backgroundwork.class
public class BackgroundWorker extends AsyncTask<String,Void,String> {
Context context;
AlertDialog alertDialog;
public AsyncResponse delegate = null;
BackgroundWorker (Context ctx) {
context = ctx;
}
// Http MySQL stuffs
#Override
protected void onPreExecute() {
alertDialog = new AlertDialog.Builder(context).create();
alertDialog.setTitle("Login Status");
}
#Override
protected void onPostExecute(String result) {
//LoginActivity.get=result;
//delegate.processFinish(result);
alertDialog.setMessage(result);
alertDialog.show();
if(result.contains("Remote login success")){
Intent i = new Intent(LoginActivity.this, MainpanelActivity.class); // ERROR HERE, FIRST ARGUMENT IS NOT AN ENCLOSING CLASS
i.putExtra("email", this.email); /
startActivity(i);
}
}
}
However, I got a "xxx is not an enclosing class error" in the onpostexecute() when I try starting a new activity (login success, jumps to another activity)
you can call the activity from following code,
if(result.contains("Remote login success")){
Intent i = new Intent(context, MainpanelActivity.class); //use context here
i.putExtra("email", this.email);
startActivity(i);
}