Android Custom Toast Message not working in a separate class - java

I have created the following method for custom toast.
public void customToastMessage(String message){
LayoutInflater inf = (LayoutInflater)con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inf.inflate(R.layout.custom_toast_layout,(ViewGroup)findViewById(R.id.myCustomToast));
TextView toastMessage = layout.findViewById(R.id.myCustomToastText);
toastMessage.setText(message);
Toast warningMessage = Toast.makeText(con, message, Toast.LENGTH_LONG);
warningMessage.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 10);
warningMessage.setView(layout);
warningMessage.show();
}
As long as this method exists in MainActivity, it works fine but when I move it to a separate class I get:
"java.lang.IllegalStateException: Could not execute method for android:onClick at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:389)".
What do I need to change in my class below?
public class MyCustomUI extends AppCompatActivity {
private static Context con;
public MyCustomUI(Context con){
this.con = con;
}
public void customToastMessage(String message){
LayoutInflater inf = (LayoutInflater)con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inf.inflate(R.layout.custom_toast_layout,(ViewGroup)findViewById(R.id.myCustomToast));
TextView toastMessage = layout.findViewById(R.id.myCustomToastText);
toastMessage.setText(message);
Toast warningMessage = Toast.makeText(con, message, Toast.LENGTH_LONG);
warningMessage.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 10);
warningMessage.setView(layout);
warningMessage.show();
}
}

I'm guessing your problem is when you inflate your layout:
View layout = inf.inflate(R.layout.custom_toast_layout,(ViewGroup)findViewById(R.id.myCustomToast));
I'm also guessing the problem is (ViewGroup)findViewById(R.id.myCustomToast). You are trying to look for a View/ViewGroup that does not exist on that class but on your MainActivity.
Pass it as an argument to your method (just the relevant part):
public void customToastMessage(String message, ViewGroup customToast){
LayoutInflater inf = (LayoutInflater)con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inf.inflate(R.layout.custom_toast_layout, viewgroup);

Related

Android - Custom Toast Class

I am trying to create a class that it´s supossed to show a toast every time that an object of this class is instaciated.
I want to do this so that I don´t have the same toast code repeated in every activity.
public class Toast extends android.widget.Toast {
String toast_text;
Context toast_context;
public Toast(String toast_text, Context toast_context) {
this.toast_text = toast_text;
this.toast_context = toast_context;
Toast toast = android.widget.Toast.makeText(this.toast_context.this, this.toast_text, Toast.LENGTH_LONG);
ViewGroup view = (ViewGroup) toast.getView();
view.setBackgroundResource(R.drawable.background_global);
TextView messageTextView = (TextView) view.getChildAt(0);
messageTextView.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
messageTextView.setTextSize(35);
Typeface face_font = Typeface.createFromAsset(getAssets(), "res/font/aldrich.ttf");
messageTextView.setTypeface(face_font);
messageTextView.setTextColor(Color.CYAN);
toast.show();
}
}
These are the following erros:
On the constructor: "There is no default constructor available in "android.widget.toast";
On the first error: " ')' expected";
On the second error: "Cannot resolve method "getAssets" ".
Use toast_context that you receive through constructor to create toast and access asset
Toast toast = android.widget.Toast.makeText(toast_context, toast_text, Toast.LENGTH_LONG);
Typeface face_font = Typeface.createFromAsset(toast_context.getAssets(), "res/font/aldrich.ttf");
Beside this, You should use other name than Toast to create custom toast
class MyToast extends android.widget.Toast {
public MyToast(String toast_text, Context toast_context) {
super(toast_context);
...
}
}

How to change the background color of every item in a ListView?

I am developing an app which has a text message interface (something like Facebook Messenger, Whatsapp, etc). I want to be able to change the background color of all the chat bubbles (a ListView of TextViews) sent by the user when they pick a new color (in a NavigationView).
However, with the current code that I have, I only am able to change the color after the EditText used to compose the message is clicked again. Or I am able to only edit the first bubble sent, but as soon as the color is changed.
Here's what I tried :
ItemColor1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
Toast.makeText(activity, "Couleur mise à jour", Toast.LENGTH_SHORT).show();
currentTheme = position;
SharedPreferences.Editor editor = pref.edit();
editor.putInt("indexColorSelected",currentTheme);
editor.apply();
chatAdapter.notifyDataSetChanged();
//the following changes only the first message sent
for(int i=0; i<chatAdapter.getCount(); i++){
ChatData message = chatMessageList.get(position);
TextView msg = activity.findViewById(R.id.text);
msg.setText(message.body);
msg.setBackgroundResource(R.drawable.user_color1);
}
}
});
ChatData is a custom Class that I created which looks like this :
public class ChatAdapter extends BaseAdapter {
private static LayoutInflater inflater = null;
private ArrayList<ChatData> chatMessageList;
private Context mContext;
ChatAdapter(Activity activity, ArrayList<ChatData> list) {
mContext = activity;
chatMessageList = list;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
...
}
Color drawable:
<corners
android:bottomRightRadius="5dp"
android:radius="40dp"/>
<gradient
android:angle="45"
android:endColor="#01f1fa"
android:startColor="#0189ff"
android:type="linear" />
</shape>
getView() method of the Adapter:
public View getView(int position, View convertView, ViewGroup parent) {
ChatData message = chatMessageList.get(position);
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.msglist, parent, false);
TextView msg = vi.findViewById(R.id.text);
msg.setText(message.body);
LinearLayout layout = vi.findViewById(R.id.message_layout);
LinearLayout parent_layout = vi.findViewById(R.id.message_layout_parent);
inflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// if message is mine then align to right
if (message.isMine) {
layout.setGravity(Gravity.RIGHT);
int couleurBubble = getCouleurSelectionnee();
switch(couleurBubble){
case R.color.c1: msg.setBackgroundResource(R.drawable.user_color1); break;
case R.color.c2: msg.setBackgroundResource(R.drawable.user_color2); break;
case R.color.c3: msg.setBackgroundResource(R.drawable.user_color3); break;
case R.color.c4: msg.setBackgroundResource(R.drawable.user_color4); break;
case R.color.c5: msg.setBackgroundResource(R.drawable.user_color5); break;
case R.color.c6: msg.setBackgroundResource(R.drawable.user_color6); break;
case R.color.c7: msg.setBackgroundResource(R.drawable.user_color7); break;
case R.color.c8: msg.setBackgroundResource(R.drawable.user_color8); break;
default: break;
}
parent_layout.setGravity(Gravity.RIGHT);
}
// If not mine then align to left
else {
layout.setGravity(Gravity.LEFT);
msg.setBackgroundResource(R.drawable.bot_chat);
parent_layout.setGravity(Gravity.LEFT);
}
return vi;
}
I don't really know where to go from here so any kind of help would be appreciated. If you want me to provide more code, let me know and I will.
Thank you.
I'm sharing how I would do it. Maybe, this can help you.
There's some strange issue because you are calling notifyDataSetChanged(). This would be enough to re-draw all message bubbles.
My ideia is:
Add a int variable to the adapter class (mColorResource). This variable will point to the proper drawable that should be used (like R.drawable.user_color1).
public class ChatAdapter extends BaseAdapter {
int mColorResource;
ChatAdapter(Activity activity, ArrayList<ChatData> list, int initialColorResource) {
mContext = activity;
chatMessageList = list;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// You must receive the color on the construtor
mColorResource = initialColor;
}
// Use this method to update the color (when user select a new color)
public void setColor(int newColorResource) {
mColorResource = newColorResource;
}
public View getView(int position, View convertView, ViewGroup parent) {
...
// Note how this if-else is cleaner now
if (message.isMine) {
layout.setGravity(Gravity.RIGHT);
msg.setBackgroundResource(mColorResource);
parent_layout.setGravity(Gravity.RIGHT);
} else {
layout.setGravity(Gravity.LEFT);
msg.setBackgroundResource(R.drawable.bot_chat);
parent_layout.setGravity(Gravity.LEFT);
}
...
}
}
Then, when a color is selected, find the proper drawable based on the view clicked and pass it to the adapter:
ItemColor1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
Toast.makeText(activity, "Couleur mise à jour", Toast.LENGTH_SHORT).show();
currentTheme = position;
SharedPreferences.Editor editor = pref.edit();
editor.putInt("indexColorSelected", currentTheme);
editor.apply();
// Here, you send the proper drawable...
// I'm not sure how you convert color selected to the drawable
// So, add your logic to convert the button clicked to a drawable here
// like R.drawable.user_color1
chatAdapter.setColor(R.drawable.NAME_OF_THE_COLOR);
// Request to re-draw all items from the list (all bubbles)
chatAdapter.notifyDataSetChanged();
}
});
Also, on your activity, you create the adapter with the last used color. Something like:
#Override
protected void onCreate(#Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
// Set a default color (if user is open you app for the first time)
int chatColor = R.drawable.user_color1;
// Add your logic to read the shared preference and convert that last color used to a valid drawable.
// Like chatColor = pref.getInt(indexColorSelected, R.drawable.user_color1) etc....
// Set the color in the adapter.
chatAdapter = newAdapter(this, mChatDataList, chatColor);
}

Add item to a specific column in ListView Adapter

I have an increment system and I want when onClick to save value from DialogAlert in a column in ListView Adapter.
Here is my Adapter:
public class VanzatorProduseList extends ArrayAdapter<VanzatorProduse> {
private Activity context;
private SparseBooleanArray selectedListItemsIds;
private List<VanzatorProduse> vanzatorProduseList;
public VanzatorProduseList(Activity context, List<VanzatorProduse> vanzatorProduseList){
super(context, R.layout.list_produse_vanzator, vanzatorProduseList);
this.context = context;
selectedListItemsIds = new SparseBooleanArray();
this.vanzatorProduseList = vanzatorProduseList;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View listViewItem = inflater.inflate(R.layout.list_produse_vanzator, null, true);
TextView textViewProdus1 = (TextView) listViewItem.findViewById(R.id.textViewProdus1);
TextView textViewPret1 = (TextView) listViewItem.findViewById(R.id.textViewPret1);
final TextView textViewCantitate1 = (TextView) listViewItem.findViewById(R.id.textViewCantitate1);
final VanzatorProduse vanzatorProduse = vanzatorProduseList.get(position);
textViewProdus1.setText(vanzatorProduse.getProdus());
textViewPret1.setText(vanzatorProduse.getPret());
textViewCantitate1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// custom dialog
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.dialog_alert);
dialog.setTitle("Alege Canitatea");
// set the custom dialog components - text, image and button
final Button dialogBtn = (Button) dialog.findViewById(R.id.dialog_btn);
final ElegantNumberButton elegantNumberButton = (ElegantNumberButton) dialog.findViewById(R.id.elegantNumberButton);
// if button is clicked, close the custom dialog
dialogBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String num = elegantNumberButton.getNumber();
vanzatorProduseList.add(num);
dialog.dismiss();
}
});
dialog.show();
}
});
return listViewItem;
}
Here is what I tried but I got an error and no idea what to do next :
String num = elegantNumberButton.getNumber();
vanzatorProduseList.add(num);
Error:
'add(com.dev.darius.neglije.Vanzator.ListaProduse.VanzatorProduse)' in 'java.util.List' cannot be applied to '(java.lang.String)'
Here I'm stuck I want to display in TextView called textViewCantitate1.
Hope you understand.
As stated in earlier answers by #jibrahim:
You are trying to add String type into List vanzatorProduseList. You can add only VanzatorProduse type into vanzatorProduseList list. So, the cause of the problem is:
String num = elegantNumberButton.getNumber();
vanzatorProduseList.add(num);
You need to do something like this Create Object of your Custom class and assign value to that:
String num = elegantNumberButton.getNumber();
VanzatorProduse numVanProObject = new VanzatorProduse();
numVanProObject .setNumber(num );
vanzatorProduseList.add(numVanProObject );
But your custom call should have method to cater this type issue
Edit: Do not forget to call notifyDataSetChanged() method to refresh the list
VanzatorProduse producse = new VanzatorProduse();
producse.setProdus("add value here")
vanzatorProduseList.add(producse);
You are trying to add String type into List<VanzatorProduse> vanzatorProduseList. You can add only VanzatorProduse type into vanzatorProduseList list. So, the cause of the problem is:
String num = elegantNumberButton.getNumber();
vanzatorProduseList.add(num);
In your code you have following lines:
final VanzatorProduse vanzatorProduse = vanzatorProduseList.get(position);
textViewProdus1.setText(vanzatorProduse.getProdus());
textViewPret1.setText(vanzatorProduse.getPret());
So, might be you add num value into vanzatorProduse.setProdus(num) or any other appropriate field and then add it into the list:
vanzatorProduseList.add(vanzatorProduse);

Calling new activity from an item inside a recyclerview row

I need to call a new activity, when a button inside one of my recyclerview row elements is called. Each row item in the list contains 4 buttons, one of which needs to open a new activity which will be used to edit the data in that row.
Here is the code for my button so far:
public void onBindViewHolder(CounterLayoutAdapter.ViewHolder holder, final
int position) {
final Counter counter = counterList.get(position);
//counter is a class which holds the data that will be displayed on one
//row
String comment = counter.getComment();
String name = counter.getCounterName();
int number = counter.getCurrentValue();
//LocalDate modifyDate = counter.getLastModifyDate();
Button up = holder.itemView.findViewById(R.id.buttonUp);
Button down = holder.itemView.findViewById(R.id.buttonDown);
Button reset = holder.itemView.findViewById(R.id.buttonReset);
Button edit = holder.itemView.findViewById(R.id.buttonEdit);
Button delete = holder.itemView.findViewById(R.id.buttonDelete);
// code for 4 other buttons goes here
//
edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
Since I need the activity that I open to return user inputted data for me, I am using startActivityForResult. However, as far as I can tell, this will only work inside an actual activity class.
So then I tried passing the mainactivity context to my CounterLayoutAdapter class, where all of my button code is. However, the OnBindViewHolder method still cannot access it there. So I tried to pass the context to OnBindViewHolder, but that doesn't work either, as it won't override the abstract class if i do that..
So, how on earth can I call a new activity here?
Alternatively, if there is some other way to get user input into 4 fields and return that input back to the adapter, without calling an activity, that would work as well.
EDIT: viewholder and layout inflation
public static class ViewHolder extends RecyclerView.ViewHolder implements
View.OnClickListener {
private TextView name;
private TextView comment;
private TextView number;
//private TextView date;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
comment = itemView.findViewById(R.id.textComment);
name = itemView.findViewById(R.id.textName);
number = itemView.findViewById(R.id.editTextNum);
//date = itemView.findViewById(R.id.textDate);
}
#Override
public void onClick(View view) {}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View inflatedView =
LayoutInflater.from(parent.getContext()).inflate(R.layout
.row_layout, parent, false);
return new ViewHolder(inflatedView);
}
You can call startActivityForResult() in adapter class.
Get context in adapter like Context context=holder.up.getContext();
then in your button's OnClickListener do this.
edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent=new Intent(context,ActivityYouWantToStart.class);
//Pass any extras if you want to.
((Activity)context).startActivityForResult(intent,REQUEST_CODE);
}
});
Then in your activity (which contain this recyclerView) override onActivityResult like this
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {//same REQUEST_CODE you used in adapter
if (resultCode == RESULT_OK) {
//Do your thing and get the data you want.
adapter.onDataReady(Data data);//where adapter is your recycler adapter,
//and data is whatever data you want to pass to adapter
//(Data you got from the activityResult, do not confuse it with onActivityResult's parameter 'Intent data')
}
}
}
Finally in your Recycler Adapter class, define onDataReady() function like
public void onDataReady(Data data){
//Update RecyclerView with new data
}
Hope this helps. I once did this, and it works for me. Let me know if you have any problem.
As you see , you do not have to findViewById in onBindViewHolder.
public void onBindViewHolder(CounterLayoutAdapter.ViewHolder holder, final
int position) {
final Counter counter = counterList.get(position);
//counter is a class which holds the data that will be displayed on one
//row
String comment = counter.getComment();
String name = counter.getCounterName();
int number = counter.getCurrentValue();
//LocalDate modifyDate = counter.getLastModifyDate();
holder.edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
Then you should init edit in ViewHolder constructor.
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
comment = itemView.findViewById(R.id.textComment);
name = itemView.findViewById(R.id.textName);
number = itemView.findViewById(R.id.editTextNum);
//date = itemView.findViewById(R.id.textDate);
// init four button
edit = itemView.findViewById(R.id.buttonEdit)
}

Trying to pass data from ListView to another class

So I've been stuck on this for hours. I'm trying to setup an async task that will load up an images for my listview in another class and I'm passing information that gives me an error
Any help would be appreciated!
public class TheResults extends Activity {
public static final String DEFAULTNAME = "DefaultFile";
private GETTHEIMAGE imgFetch;
private ArrayList<Item_Info> Info = new ArrayList<Item_Info>();
String Data = null;
String THESTRING = null;
TextView httpStuff;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// full screen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.theresults);
SharedPreferences Search = getSharedPreferences(DEFAULTNAME, 0);
Data = Search.getString("THERESULTS", null);
GetINFO();
populatelist();
}
private void GetINFO() {
}
}
}
private void populatelist() {
ArrayAdapter<Item_Info> adapter = new TheListAdapter();
ListView list = (ListView) findViewById(R.id.listings);
list.findFocus();
list.getWindowToken();
list.setAdapter(adapter);
}
public class TheListAdapter extends ArrayAdapter<Item_Info> {
public TheListAdapter() {
super(TheResults.this, R.layout.items, Info);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View item_View = convertView;
ImageHolder holder = null;
if (item_View == null) {
item_View = getLayoutInflater().inflate(R.layout.items, parent, false);
Item_Info CurrentItem = Info.get(position);
holder = new ImageHolder();
holder.ICON_IMG = (ImageView)item_View.findViewById(R.id.icon_image);
holder.ICON_IMG.setTag(CurrentItem.getItemPIC());
Drawable MYIMG = imgFetch.GetTheImagedata(this, holder.ICON_IMG);
holder.ICON_TITLE = (TextView)item_View.findViewById(R.id.icon_title);
holder.ICON_TITLE.setText(CurrentItem.getItemTITLE());
holder.ICON_LOCATION = (TextView)item_View.findViewById(R.id.icon_location);
holder.ICON_LOCATION.setText(CurrentItem.getItemLOCATION());
holder.ICON_PRICE = (TextView)item_View.findViewById(R.id.icon_price);
if (CurrentItem.getItemPRICE() == null) {
holder.ICON_PRICE.setText(CurrentItem.getItemPRICE());
holder.ICON_PRICE.setBackgroundResource(R.drawable.tempbg);
} else {
holder.ICON_PRICE.setBackgroundResource(R.drawable.pricebg);
holder.ICON_PRICE.setText(CurrentItem.getItemPRICE());
}
holder.ICON_DATE = (TextView)item_View.findViewById(R.id.icon_date);
holder.ICON_DATE.setText(CurrentItem.getItemLOCATION());
}else{
holder = (ImageHolder)item_View.getTag();
}
return item_View;
}
}
static class ImageHolder{
ImageView ICON_IMG;
TextView ICON_TITLE;
TextView ICON_LOCATION;
TextView ICON_PRICE;
TextView ICON_DATE;
}
}
By looking at the logcat after the line
06-21 19:15:06.887: E/AndroidRuntime(11408): FATAL EXCEPTION: main
is the exception
java.lang.NullPointerException
which tells us that something is null and that is throwing the exception. If we look for the first line of the code that references your project we will see where the problem occurs. Here, it happens to be the next line in logcat
at com.clistc.TheResults$TheListAdapter.getView(TheResults.java:178)
Which tells us that the line is 178 of TheResults.java and that it is inside the getView() method. We have established that it is this line
Drawable MYIMG = imgFetch.GetTheImagedata(this, holder.ICON_IMG);
which means that imgFetch is probably null and you try to call a function on it which returns null since the variable is null. I don't know what that variable is but it isn't being initialized before this line
Edit
imgFetch isn't initialized anywhere. It is declared here
private GETTHEIMAGE imgFetch;
but you never initialize it by giving it a value. You need to do something like
private GETTHEIMAGE imgFetch = new GETTHEIMAGE();
assuming it has an empty constructor

Categories

Resources