I have a list array adapter.I use a template layout for each elements of "arraylist".I play sound by "onclicklistener" defined on image in my "CustomArrayAdapter.java" class.
by the way i define "onStop()" as override in related activity.
when i click on image,sound plays,but when i test switching activity by hitting home button on mobile,
sound continue playing.
part of my code in Customarraylist.java :
ImageView playIconSecondLanguageImage = (ImageView)list_layout.findViewById(R.id.playIconsecondLanguageImageviewId); playIconSecondLanguageImage.setImageResource(customWord.getmPlayIconImageId();
playIconSecondLanguageImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
releaseMediaPlayer();// to stop another playing when another start instantly
mMediaPlayer =
MediaPlayer.create(v.getContext(),customWord.getmSecondLanguageSoundId());
mMediaPlayer.start();
mOnCompletionListener();
}
});
and part of my code in NumberActivity.java:
}//End of Oncreat
public void releaseMediaPlayer(){
if(mediaPlayer!=null)
{
mediaPlayer.release();
mediaPlayer = null;
}
}
protected void onStop() {
super.onStop();
releaseMediaPlayer();
}
}//End of class NumbersActivity
problem is that mediaplayer in NumbersActivity.java is different whith mediaplayer which i defined in
"Customarraylist.java" to play sound.
my CustomArrayAdapter.java is:
package com.example.customarrayadapter;
import android.app.Activity;
import android.app.Application;
import android.media.MediaPlayer;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import java.util.ArrayList;
public class CustomArrayAdapter extends ArrayAdapter<CustomWord> {
// States
private int mColorId;
private MediaPlayer mMediaPlayer;
// to avoid creat new object(here,new medaPlayer), this codes below take out from the Onclick listener
// and define here******************
private MediaPlayer.OnCompletionListener mOnCompletionListener = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
Toast.makeText(getContext(),"Play finished!",Toast.LENGTH_SHORT).show();
// check is it need to mPlayer anymore or not,to free up memeory usage by the player
releaseMediaPlayer();
}
};
//****************************************
// need Constructor
public CustomArrayAdapter(Activity context, ArrayList<CustomWord>arrayList,int colorId){
super(context,0,arrayList);
this.mColorId = colorId;
}
// use getView override method to move elements of arraylist one by one by its position,to listview
// getView method, steps:
// a. get position of elements in "customWord"(get one from 2 elements in CustomWord" Type,and pass to
// arraylist of type CustomWord,then 2 from 2 elemnts moves),by "position" by "getItem(position)"
// b. prepare a view (convertview),to locate our "list_layout", in it
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
// a.
final CustomWord customWord = getItem(position);
// Define "list_layout" view, to get "convertView" layout in it
View list_layout = convertView;
// if list_layout is null,then put "customlist_layout" in it
if(list_layout==null){
list_layout = LayoutInflater.from(getContext()).inflate(R.layout.customlist_layout,parent,false);
}
// 1 image (source image) + 2 words + 2 image(language flags) + 2 images(olay icon), in customlist_layout.xml so ,so need 2 textview + 1 imageview
// Find the ImageView in the list_item.xml layout with the ID list_item_icon
// ImageView 1 (SourceImage)
ImageView ImageSourceiconView = (ImageView) list_layout.findViewById(R.id.ImageSourceViewId);
// set the image to iconView
ImageSourceiconView.setImageResource(customWord.getmDataResourceId());
// put elements(2 elements) in "CustomWord" one by one into (2 textviews),each textview (one textview to second textview)
// textview 1
TextView secondLanguage_tv = (TextView)list_layout.findViewById(R.id.SecondLanguageId_Textview_ListView);
secondLanguage_tv.setText(customWord.getmSecondLanguageString());
// textview 2
TextView defualtLanguage_tv = (TextView)list_layout.findViewById(R.id.DefualtLanguageId_Textview_ListView);
defualtLanguage_tv.setText(customWord.getmDefualtLanguageString());
// Default Flag Language Image View
// ImageView 2 (Default Flag)
ImageView defaultLanguageFlag = (ImageView) list_layout.findViewById(R.id.DefaultLanguageFlag);
// set the image to iconView
defaultLanguageFlag.setImageResource(customWord.getmDefaultLanguageFlag());
// Second Flag Language ImageView
// ImageView 3 (Second Flag)
ImageView secondLanguageFlag = (ImageView) list_layout.findViewById(R.id.SecondLanguageFlag);
// set the image to iconView
secondLanguageFlag.setImageResource(customWord.getmSecondLanguageFlag());
// source playIcon imageview
ImageView playIconDefualtLanguageImage = (ImageView)list_layout.findViewById(R.id.playIcondefaultLanguageImageViewId);
playIconDefualtLanguageImage.setImageResource(customWord.getmPlayIconImageId());
playIconDefualtLanguageImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
releaseMediaPlayer();// to stop another playing when another start instantly
mMediaPlayer = MediaPlayer.create(v.getContext(),customWord.getmDefaultLanguageSoundId());
mMediaPlayer.start();
mOnCompletionListener();
}
});
// 2nd play icon image set
ImageView playIconSecondLanguageImage = (ImageView)list_layout.findViewById(R.id.playIconsecondLanguageImageviewId);
playIconSecondLanguageImage.setImageResource(customWord.getmPlayIconImageId());
playIconSecondLanguageImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
releaseMediaPlayer();// to stop another playing when another start instantly
mMediaPlayer = MediaPlayer.create(v.getContext(),customWord.getmSecondLanguageSoundId());
mMediaPlayer.start();
mOnCompletionListener();
}
});
// Default Sound Language Image View
// ImageView 4 (Default Language sound)
// set color of layout by mcolorId to sync with name of category in main layout.xml
View textContainer = list_layout.findViewById(R.id.CustomListId);
// ContextCompat is for creat color from getColor
// getColor get color of getContext Object and its color integer id
int color = ContextCompat.getColor(getContext(),mColorId);
textContainer.setBackgroundColor(color);
return list_layout;
}//End of getviw
private void mOnCompletionListener() {
}
public void releaseMediaPlayer(){
if(mMediaPlayer!=null)
{
mMediaPlayer.release();
mMediaPlayer = null;
}
}
public void setmMediaPlayer(MediaPlayer mMediaPlayer) {
this.mMediaPlayer = mMediaPlayer;
}
public MediaPlayer getmMediaPlayer() {
return mMediaPlayer;
}
}
You can achieve your needs using Interface :
Create an Interface and call it (e.g. PlayerCallBack) :
public interface PlayerCallBack {
void onMediaPlayerClickEvent(int position);
}
In your CustomArrayAdapter add a constructor as follows :
public CustomArrayAdapter(Context context, PlayerCallBack playerCallBack, ArrayList<CustomWord> customWords) {
this.context = context;
this.playerCallBack = playerCallBack;
this.customWords = customWords;
}
Change the code of ImageView click listener to this :
playIconSecondLanguageImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playerCallBack.onMediaPlayerClickEvent(position);
}
});
In your NumbersActivity :
CustomArrayAdapter customArrayAdapter = new CustomArrayAdapter(customWords, getApplicationContext(), new PlayerCallBack() {
#Override
public void onMediaPlayerClickEvent(int position) {
mMediaPlayer = MediaPlayer.create(v.getContext(), customWord.getmSecondLanguageSoundId());
mMediaPlayer.start();
}
});
No you can play with MediaPlayer as you want
You have to control activity lifecycles and then you have to switch on/off sound accordingly to your needs.
enter link description here
After googling i found a solution to this.
sound source is playing in "CustomArrayAdapter.java" class that is set in NumbersActivity.java class as Activity. after clicking on image to play sound,sound is playing, when hit "Home" mobile button ,Activating "Activity:NumbersActivity",goes in
onPause then onStop state. but sound is playing.
one way is to find process running in background when "Home" button is hitted.
and that is "com.example.customarrayadapter",so i can find the process and kill it by its id :
codes are written in Activity: NumbersActivity
} //End Of Oncreate
protected void onStop() {
super.onStop();
ActivityManager manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> services = manager.getRunningAppProcesses();
String service1name = services.get(0).processName;
int processPid = services.get(0).pid;
Log.d("*Process PID*","**********");
Log.d(activityNameString,"onStop invoked");
Log.d(activityNameString,"Process Id is : "+service1name+"\n");
android.os.Process.killProcess(processPid);
}
}//End of NumbersActivity class
Related
My app has a layout looking like this
LAyout
And this is inflated by a adapter, creating a listview containing many such layouts with the contents of the layout changing according to the position.
Everything is ok upto this.
Now I need to set a onClickListener on the playButton and it will play a very short music and its imagesrc will change from play image to pause image.
I implemented the the playing of music in the adapter itself by setting an onClickListeners on each of playButton in the layouts I inflated. in getView(). (is this the best way to do this?)
Now that also worked perfectly untill I tried changing the imagesrc when the playButtton will be Clicked.
What happens is the last layout that is inflated by the adapter only its imagesrc changes on clicking. That is no matter which layout's playButton I click on, the correct music plays, but the imagesrc is changed of the playButton in the last layout inflated last by the adapter.
Why is this happening?
Here is the code of my adapter
public class MyAdapter extends ArrayAdapter<MyCustomObject> {
private static AudioManager mAudioManager;
private static MediaPlayer mMedia;
private ImageView mPlayButton;
private Context mContext;
/**
* A custom created Constructor
* this is used to inflate a custom created layout file
*/
public MyAdapter(Activity context, ArrayList<MyCustomObject> wordArrayList) {
super(context, 0, wordArrayList);
this.mContext = context;
}
private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mPlayButton.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_action_play));
releaseMediaPlayer();
}
};
public static AudioManager.OnAudioFocusChangeListener mOnAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
#Override
public void onAudioFocusChange(int focusChange) {
if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT ||
focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
mMedia.pause();
mMedia.seekTo(0);
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
mMedia.start();
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
releaseMediaPlayer();
}
}
};
public static void releaseMediaPlayer() {
if (mMedia != null) {
mMedia.release();
mMedia = null;
mAudioManager.abandonAudioFocus(mOnAudioFocusChangeListener);
}
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
View currentView = convertView;
if (currentView == null)
currentView = LayoutInflater.from(getContext()).inflate(R.layout.layout_to_be_inflated, parent, false);
final MyCustomObject currentObject = getItem(position);
/**Setting the {#id englishID} of the miwokenglishlist.xml
* to the the desired english value
*/
//Getting the ID
TextView defalutTextView = (TextView) currentView.findViewById(R.id.englishID);
//Changing the text of the view
defalutTextView.setText(currentWordObject.getEnglishWord());
/**
* Setting the {#id miwokID} of the miwokenglishlist.xml
* to the current miwok word
*/
// Getting the ID
TextView secondaryTextView = (TextView) currentView.findViewById(R.id.secondID);
// Changing the text to the current miwok word
miwokTextView.setText(currentObject.getSecondWord());
/**
* Checking whether current Word object has a image associated with it or not
*/
// Getting the image id from the current word object
int currImageID = currentObject.getImageResourceID();
// Getting the ID for the image in miwokenglishlist.xml
ImageView imageViewID = (ImageView) currentView.findViewById(R.id.imageID);
// if image is present for the current object
if (currImageID != -1) {
// Setting the image on the layout
imageViewID.setImageResource(currImageID);
}
// if image is not present for the current object
else {
imageViewID.setVisibility(View.GONE);
}
mPlayButton = (ImageView) currentView.findViewById(R.id.imageButton);
mPlayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// If there are already underlying resources
releaseMediaPlayer();
int result = mAudioManager.requestAudioFocus(mOnAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mMedia = MediaPlayer.create(getContext(), currentWordObject.getPronunciation());
mMedia.start();
mMedia.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
`//Changing the playButton resource to pause`
mPlayButton.setImageDrawable(ContextCompat.getDrawable(mContext,
R.drawable.ic_action_pause));
}
});
mMedia.setOnCompletionListener(mCompletionListener);
}
}
});
// Returning the modified inflated View
return currentView;
}
}
So how do i do this?
UPDATE: I solved the issue, i was calling setDrawablesrc on the mPlayButton id which referred to the playButton in the last layout which was inflated. So, I called the setDrawablesrc on the view that was passed in the onClick method of the onClickListener.
Here is the updated code
mPlayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View view) {
// If there are already underlying resources
releaseMediaPlayer();
int result = mAudioManager.requestAudioFocus(mOnAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
//Storing the view in the instance variable to refer to it in the onCompletionlIstener of the MediaPlayer
mPlayButtonView = (ImageView) view;
mMedia = MediaPlayer.create(getContext(), currentWordObject.getPronunciation());
mMedia.start();
mMedia.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
//Changing the imagesrc of the view that is passed
((ImageView)view).setImageDrawable(ContextCompat.getDrawable(mContext,
R.drawable.ic_action_pause));
}
});
mMedia.setOnCompletionListener(mCompletionListener);
}
}
});
And in the onCompletionListener i took the instance variable and changed its imagesrc.
Worked perfectly! :)
Now one question lies, is this the best way to do this?
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
i finally figured out where to find most of this.
but now i need to know how to test one part of this program for a username.
My goal is if the user doesn't put anything in the program then don't allow anything to continue.
This is a big app. I have like 3 layout files and 3 java files.
Any help would be good if you need me to send the file i can.
package edu.jones.demogamestartarrayadaptor;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
//import android.view.KeyEvent;
import android.view.View;
//import android.view.View.OnKeyListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
//import android.widget.Toast;
public class GameControlMainActivity extends ListActivity
{
//Class-wide variables for data passed/returned
private String userName = "";
//Use an int for gameLevel,naturally...but, this requires
//use of various methods to convert to String and back!
private int gameLevel = 1;
private EditText nameEntryET;
private TextView gameLevelAnnouncerTV;
private TextView gameLevelTV;
Button doneButton;
//This TV prompts user to enter name in the EditText
//Then, it is made invisible
private TextView namePromptTV;
//These two start out invisible and then show the name
private TextView nameSetTV;
private TextView nameEntTV;
//Array of choices for user
static final String[] CHOICES = new String[]
{
"Read directions",
"Play Game",
"Quit"
};
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Set up View ids
nameEntryET = (EditText)findViewById(R.id.enter_nameET);
gameLevelAnnouncerTV = (TextView) findViewById(R.id.game_level_announcer_TV);
gameLevelTV = (TextView) findViewById(R.id.game_level_TV);
//Set the game level in the TextView
gameLevelTV.setText(Integer.toString(gameLevel));
namePromptTV = (TextView)findViewById(R.id.name_prompt_tv);
nameSetTV = (TextView)findViewById(R.id.name_set_tv);
nameEntTV = (TextView)findViewById(R.id.name_entered_tv);
//Set Done button listener to get user's name
doneButton = (Button) findViewById(R.id.doneBtn);
setDoneButtonListener();
//Set up ArrayAdaptor for the options
setListAdapter(new ArrayAdapter<String>
(this, android.R.layout.simple_list_item_1, CHOICES));
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
getListView().setTextFilterEnabled(true);
//Set up the listener for user clicks on the list
setListClickListener();
//this toast is for when it opens
Toast.makeText(this, "yo whats up", Toast.LENGTH_SHORT).show();
}//END onCreate
private void setDoneButtonListener()
{
doneButton.setOnClickListener
(
new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//Get user's name when button is clicked
//Call method to set text and hide button
setUserNameAndHideButton();
}
}
);//END setOnClickListener
}//END setDoneButtonListener
//Sets up username in its TextView, and game level Views,
//then hides the other Views & button
private void setUserNameAndHideButton()
{
userName = nameEntryET.getText().toString();
doneButton.setVisibility(View.GONE);
Toast.makeText(this, "Your name has been entered", Toast.LENGTH_SHORT).show();
//After getting the input, hide the EditText
//VISIBLE(0), INVISIBLE(4) or GONE(8)
nameEntryET.setVisibility(View.INVISIBLE);
namePromptTV.setVisibility(View.GONE);
nameEntTV.setText(userName);
nameSetTV.setVisibility(View.VISIBLE);
nameEntTV.setVisibility(View.VISIBLE);
gameLevelAnnouncerTV.setVisibility(View.VISIBLE);
gameLevelTV.setVisibility(View.VISIBLE);
}//END setUserNameAndHideButton
//Set up the listener for the ListView to interpret user clicks
private void setListClickListener()
{
//Set up the click listener for the options
getListView().setOnItemClickListener
(
new OnItemClickListener()
{
//#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
switch(arg2)
{
case 0: launchDirectionsPage();
break;
case 1: startGame();
break;
case 2: finish();
break;
default: break;
}
}
}//END OnItemClickListener
);//END setOnItemClickListener
}//END setListClickListener
//Launch a simple activity to show a scroll view of directions
protected void launchDirectionsPage()
{
//Set up Intent
Intent launchDirections = new Intent(this, DirectionsPageActivity.class);
startActivity(launchDirections);
}//END launchDirectionsPage
//Launch the activity that allows user to input new game value
//Upon return the onActivityResult method is called
protected void startGame()
{
//Set up Intent to launch other activity: PlayGame
Intent launchGame = new Intent(this, PlayGameActivity.class);
//Info added to the Intent's Bundle to pass to PlayGameActivity
launchGame.putExtra("bdl_username", userName);
launchGame.putExtra("bdl_gamelevel", gameLevel);
startActivityForResult(launchGame, 0);
}//END startGame
//This method will be called when the startGame activity terminates
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == 0 && resultCode == RESULT_OK)
{
//Reset the views to possibly updated info returned in the Intent
//First, access the Bundle's values
userName = data.getExtras().getString("bdl_returnUserName");
gameLevel = data.getExtras().getInt("bdl_returnGameLevel");
//Update the user name & game level with values from other activity
nameEntTV.setText(userName);
gameLevelTV.setText(Integer.toString(gameLevel));
}
}//END onActivityResult
#Override
protected void onSaveInstanceState (Bundle outState)
{
super.onSaveInstanceState(outState);
//Add the username and game level to the Bundle
outState.putString("bdl_savedusername", userName);
outState.putInt("bdl_savedgamelevel", gameLevel);
}//END onSaveInstanceState
#Override
public void onRestoreInstanceState (Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
//Restore the username and game level from the Bundle
userName = savedInstanceState.getString("bdl_savedusername");
gameLevel = savedInstanceState.getInt("bdl_savedgamelevel");
}//END onRestoreInstanceState
}//END GameControlMainActivity
If you are asking to stop if the username is not entered, just do this:
private void setDoneButtonListener()
{
doneButton.setOnClickListener
(
new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if (nameEntryET.getText().toString().equals("")) {
Toast.makeText(this, "Enter a username", Toast.LENGTH_LONG).show();
} else {
//Get user's name when button is clicked
//Call method to set text and hide button
setUserNameAndHideButton();
}
}
}
);//END setOnClickListener
}//END setDoneButtonListener
if nameEntryET does not have a value entered, nameEntryET.getText().toString() will return an empty string.
I have created a class of type BaseAdapter that is populated with buttons - when you click on a button I want to load a new intent. This has proven difficult on two levels:
You cannot associate the event with the button (one that creates a new intent) inside the Adapter. This is why I send the Buttons as an array to my Adapter (this solution works, but it is messy)
Even though my buttons are created inside the same Activity - they cannot create a new intent from that Activity. The exeption is so great that I have not even gotten a try...catch statement to work.
I have tried reflection, creating the buttons inside the activity and passing them through, passing the context (to call context.startIntent(...))
My question: can someone show me how to create a ButtonAdapter where each button creates a new Intent - even of the same type as the original Activity?
UPDATE: Here is the code because I am getting answers from people who think I am struggling with onClickListeners:
public class ButtonAdapter extends BaseAdapter
{
private Context _context;
private Button[] _button;
public ButtonAdapter(Context c, Button[] buttons)
{
_context = c;
_button = buttons;
}
// Total number of things contained within the adapter
public int getCount()
{
return _button.length;
}
// Require for structure, not really used in my code.
public Object getItem(int position)
{
return _button[position];
}
// Require for structure, not really used in my code. Can
// be used to get the id of an item in the adapter for
// manual control.
public long getItemId(int position)
{
return position;
}
public View getView(int position, View convertView, ViewGroup parent)
{
_button[position].setId(position);
return _button[position];
}
}
---------------
The Activity:
public class MainActivity extends Activity
{
private GridView _gv;
private TextView _heading;
private ButtonAdapter _adapter;
public void LoadActivity(String heading)
{
try
{
Itent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.putExtra("Level", "NextPage");
intent.putExtra("Heading", heading);
startActivity(intent);
}
catch (Exception ex)
{
Toast.makeText(getApplicationContext(), String.format("Error LoadActivity: %s", ex.getMessage()), Toast.LENGTH_SHORT).show();
}
}
private void createButtonsAdapter(Button _button[])
{
_buttonadapter = new ButtonAdapter(getApplicationContext(), _button);
_gv.setAdapter(_adapter);
}
private void setupButtons()
{
Button[] _buttons = new Button[2];
String names[] = new String[]{"Button1","Button2"};
for (int i = 0; i < 2; i++)
{
_buttons[i] = new Button(this);
_buttons[i].setText(names[i]);
_buttons[i].setTag(names[i]);
_buttons[i].setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
try
{
LoadActivity(((Button)arg0).getTag().toString());
}
catch(Exception ex)
{
Toast.makeText(getApplicationContext(), String.format("Error button.onClick: %s", ex.getMessage()), Toast.LENGTH_SHORT).show();
}
}
});
}
createButtonsAdapter(_buttons);
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
_gv = (GridView)findViewById(R.id.gridview);
_heading = (TextView)findViewById(R.id.tv_heading);
Bundle params = getIntent().getExtras();
if (params == null)
{
setupButtons();
}
else if (params.containsKey("Level"))
{
_heading.setText(params.getString("Heading"));
if (params.getString("Level").equals("NextPage"))
{
//code not here yet
}
else if (params.getString("Level").equals("Chapters"))
{
//future code
}
}
}
}
Excuse the bold and caps but I have had enough silly answers to warrent this:
I HAVE TRIED PUTTING THE ONCLICKLISTENER INSIDE THE GRIDVIEW AND IT DOES NOT WORK EITHER
You cannout load an activity from a class outside that activity, even if you pass the context as a parameter. That is why I have resorted to this method, which completely bombs android, even though I have try catch statements.
Please try give me a solution in the form of a correction to my code, other code, or a tutorial that achieves what I want here. I know how to do a button adapter properly, it is the act of loading an Intent that has forced me to implement it this way.
I suggest the following,
Using a common onClick listner for all the buttons in your grid view
Set tag for all the butons in the getView func. of adapter.
Use the tag Object to decide on the intent to fire from the onClick listener.
I hope it helps..
I guess you can easily manipulate your buttons created in your class extending Base adapter. In the getView method .... if you have button b.. then do it as follows
b.setOnClickListener(new OnClickListener()
{
public void onClick()
{
// Do your stuff here ...
}
});
and if you want to start another activity on Click of this button then you need to pass the calling context to this adapter.
Once again I am answering my own question:
http://bottlecapnet.blogspot.com/2012/01/android-buttons-have-no-place-inside.html
I will just have to style TextViews as I want to see them.
I want to display an image on button click, but I have three errors in my code. What's wrong?
class name "SequencerActivity"
The type SequencerActivity must implement the inherited abstract method DialogInterface.OnClickListener.onClick(DialogInterface, int).
next.setOnClickListener(this);
The method setOnClickListener(View.OnClickListener) in the type View is not applicable for the arguments (SequencerActivity).
onClick(View v)
The method onClick(View) of type SequencerActivity must override or implement a supertype method.
Here's the code giving those errors:
public class SequencerActivity extends Activity implements OnClickListener
{
private int imageCounter = 0;
private ImageView imageLoader;
private int[] imageList = {R.drawable.f03, R.drawable.f04, R.drawable.f05, R.drawable.f06};
#Override
public void onCreate(Bundle savedInstanceState)
{
setContentView(R.layout.main);//this one is the common parent layout for all image views
super.onCreate(savedInstanceState);
/*requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);*/
//int image1 = R.drawable.image_w_lbl_0;
imageLoader = (ImageView) findViewById(R.id.imageLoader);
//imageLoader.setImageResource(image1);
Button next = (Button) findViewById(R.id.next);
Button back = (Button) findViewById(R.id.back);
next.setOnClickListener(this);
back.setOnClickListener(this);
back.setEnabled(false);
//show the default image
this.loadImage(imageList[imageCounter]);
}
#Override
public void onClick(View v)
{
int imagePath = 0;
// TODO Auto-generated method stub
switch (v.getId())
{
case R.id.next:
Log.i("Tag","tag");
if(imageCounter < imageList.length)
{
imageCounter++;
imagePath = imageList[imageCounter];
if (imageCounter==(imageList.length)-1)
{
{
ImageButton next=(ImageButton)findViewById(R.id.next);
next.setEnabled(false);
}
}
else
{
ImageButton back=(ImageButton)findViewById(R.id.back);
back.setEnabled(true);
}
}
break;
case R.id.back:
if(imageCounter > 0)
{
imageCounter--;
imagePath = imageList[imageCounter];
if (imageCounter==0)
{
ImageButton back=(ImageButton)findViewById(R.id.back);
back.setEnabled(false);
}
else
{
ImageButton next=(ImageButton)findViewById(R.id.next);
next.setEnabled(true);
}
}
break;
}
this.loadImage(imagePath);
}
private void loadImage(int imagePath)
{
imageLoader.setImageResource(imagePath);
}
}
The OnClickListener that you implement is not correct,
try to implement View.OnClickListener and not DialogInterface.OnClickListener.
You can see that in your import
import View.OnClickListener
instead of
import DialogInterface.OnClickListener
you need to import import android.view.View.OnClickListener;
So your code look like
import android.view.View.OnClickListener;
public class MainActivity extends Activity implements OnClickListener{
// Your oncreate() and rest of all code
}
// you should have method as below
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v.getId() == R.id.editText1) // just for instance
{
.. your onclick handle code
}
}
Still you are not able to resolve the error type import View.OnClickListener; then move the cursor on the View in import View.OnClickListener; It will open up pop-up then choose the Organize imports option.
Use simply import View.OnClickListener; at the top.
The OnClickListener you're implementing is the wrong one. It says it's DialogInterface.OnClickListener, while you probably want View.OnClickListener. You can correct that in the corresponding import statement.
Just do only One thing. Use "import android.view.View.OnClickListener" statement at the top of the program.
Do one thing
remove import android.content.DialogInterface.OnClickListener;
and import
android.View.View.OnClickListener
this will solve the problem
Happy Coding
Implement View.view.onClickListener
Is it possible to have a button in a Toast?
In theory, yes because you can build a custom Toast from a layout in XML, but I tried to put a button in it and couldn't get it to register the click.
Did anyone manage to do something like that?
A toast can not be clicked. It is not possible to capture a click inside a toast message.
You will need to build a dialog for that. Look at Creating Dialogs for more info.
The API on the Toast class state that a toast will never receive the focus and because a toast is not a view there is no onClick message. I would assume that therefore childs of a Toast can not be clicked as well.
A toast cant contain a button. Except that the gmail app and the gallery app in jelly beans have a semi toast that contains a button, here is how Google did it
https://gist.github.com/benvd/4090998
I guess this answers your question.
Snippet shows implementation of custom Toast that:
Have similar interface as original Toast class
Can be used as Dialog (have clickable buttons like Gmail app)
Have possibility to set length in millis
Have possibility to set show and cancel animation
Lives only with initialized Activity
Current Limitations:
No screen orientation change are supported
Usage:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
View toastView = new View(getBaseContext());
//init your toast view
ActivityToast toast = new ActivityToast(this, toastView);
//set toast Gravity ( Gravity.BOTTOM | Gravity.FILL_HORIZONTAL by default)
toast.setGravity(Gravity.CENTER);
toast.setLength(10000); //set toast show duration to 10 seconds (2 seconds by default)
Animation showAnim; // init animation
Animation.AnimationListener showAnimListener; //init anim listener
toast.setShowAnimation(showAnim);
toast.setShowAnimationListener(showAnimListener);
Animation cancelAnim; // init animation
Animation.AnimationListener cancelAnimListener; //init anim listener
toast.setCancelAnimation(showAnim);
toast.setCancelAnimationListener(showAnimListener);
toast.show(); //show toast view
toast.isShowing(); // check if toast is showing now
toast.cancel(); //cancel toast view
toast.getView(); //get toast view to update it or to do something ..
}
Sources
import android.app.Activity;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.FrameLayout;
public class ActivityToast {
public static final long LENGTH_SHORT = 2000;
public static final long LENGTH_LONG = 3000;
public static final int DEFAULT_ANIMATION_DURATION = 400;
private final Activity mActivity;
private FrameLayout.LayoutParams mLayoutParams;
private Handler mHandler = new Handler();
private ViewGroup mParent;
private FrameLayout mToastHolder;
private View mToastView;
private Animation mShowAnimation;
private Animation mCancelAnimation;
private long mLength = LENGTH_SHORT;
private Animation.AnimationListener mShowAnimationListener;
private Animation.AnimationListener mCancelAnimationListener;
private boolean mIsAnimationRunning;
private boolean mIsShown;
/**
* #param activity Toast will be shown at top of the widow of this Activity
*/
public ActivityToast(#NonNull Activity activity, View toastView) {
mActivity = activity;
mParent = (ViewGroup) activity.getWindow().getDecorView();
mToastHolder = new FrameLayout(activity.getBaseContext());
mLayoutParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
Gravity.BOTTOM | Gravity.FILL_HORIZONTAL
);
mToastHolder.setLayoutParams(mLayoutParams);
mShowAnimation = new AlphaAnimation(0.0f, 1.0f);
mShowAnimation.setDuration(DEFAULT_ANIMATION_DURATION);
mShowAnimation.setAnimationListener(mHiddenShowListener);
mCancelAnimation = new AlphaAnimation(1.0f, 0.0f);
mCancelAnimation.setDuration(DEFAULT_ANIMATION_DURATION);
mCancelAnimation.setAnimationListener(mHiddenCancelListener);
mToastView = toastView;
mToastHolder.addView(mToastView);
mToastHolder.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
cancel();
}
return false;
}
});
}
public void show() {
if (!isShowing()) {
mParent.addView(mToastHolder);
mIsShown = true;
if (mShowAnimation != null) {
mToastHolder.startAnimation(mShowAnimation);
} else {
mHandler.postDelayed(mCancelTask, mLength);
}
}
}
public void cancel() {
if (isShowing() && !mIsAnimationRunning) {
if (mCancelAnimation != null) {
mToastHolder.startAnimation(mCancelAnimation);
} else {
mParent.removeView(mToastHolder);
mHandler.removeCallbacks(mCancelTask);
mIsShown = false;
}
}
}
public boolean isShowing() {
return mIsShown;
}
/**
* Pay attention that Action bars is the part of Activity window
*
* #param gravity Position of view in Activity window
*/
public void setGravity(int gravity) {
mLayoutParams.gravity = gravity;
if (isShowing()) {
mToastHolder.requestLayout();
}
}
public void setShowAnimation(Animation showAnimation) {
mShowAnimation = showAnimation;
}
public void setCancelAnimation(Animation cancelAnimation) {
mCancelAnimation = cancelAnimation;
}
/**
* #param cancelAnimationListener cancel toast animation. Note: you should use this instead of
* Animation.setOnAnimationListener();
*/
public void setCancelAnimationListener(Animation.AnimationListener cancelAnimationListener) {
mCancelAnimationListener = cancelAnimationListener;
}
/**
* #param showAnimationListener show toast animation. Note: you should use this instead of
* Animation.setOnAnimationListener();
*/
public void setShowAnimationListener(Animation.AnimationListener showAnimationListener) {
mShowAnimationListener = showAnimationListener;
}
public void setLength(long length) {
mLength = length;
}
public View getView() {
return mToastView;
}
private Runnable mCancelTask = new Runnable() {
#Override
public void run() {
cancel();
}
};
private Animation.AnimationListener mHiddenShowListener = new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
if (mShowAnimationListener != null) {
mShowAnimationListener.onAnimationStart(animation);
}
mIsAnimationRunning = true;
}
#Override
public void onAnimationEnd(Animation animation) {
mHandler.postDelayed(mCancelTask, mLength);
if (mShowAnimationListener != null) {
mShowAnimationListener.onAnimationEnd(animation);
}
mIsAnimationRunning = false;
}
#Override
public void onAnimationRepeat(Animation animation) {
if (mShowAnimationListener != null) {
mShowAnimationListener.onAnimationRepeat(animation);
}
}
};
private Animation.AnimationListener mHiddenCancelListener = new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
if (mCancelAnimationListener != null) {
mCancelAnimationListener.onAnimationStart(animation);
}
mIsAnimationRunning = true;
}
#Override
public void onAnimationEnd(Animation animation) {
mParent.removeView(mToastHolder);
mHandler.removeCallbacks(mCancelTask);
if (mCancelAnimationListener != null) {
mCancelAnimationListener.onAnimationEnd(animation);
}
mIsAnimationRunning = false;
mIsShown = false;
}
#Override
public void onAnimationRepeat(Animation animation) {
if (mCancelAnimationListener != null) {
mCancelAnimationListener.onAnimationRepeat(animation);
}
}
};
}
My original post on github
Post that shows implementation of custom layout in this post
A custom view passed to a toast can contain anything; however, toasts cannot receive any touch events so no components that use touch events will work in a stock toast (buttons, radiobuttons, etc.). The only choice you have is to create a custom view with a button in it and add it to your layout. There are many examples of how to do this and a few libraries you can check out to see how other people are doing it.
UndoBar
MessageBar
Nurik's UndoBar
Of course you are also welcome to use the SuperToasts library I put together however it might be a little overkill for one usage. The way that I do it is outlined in the SuperActivityToast class.
You should use a Snackbar. It is in the latest android support library(at time of answer) and is compatible with older api levels. It is much easier to implement than a Dialog or custom View and has the ability to have a button unlike a Toast.
Download Android Support Library from Extras in the SDK Manager(revision 22.2.1 or later).
In the build.gradle add this to the class dependencies: com.android.support:design:22.2.0.
Implement:
Snackbar.make(this.findViewById(android.R.id.content), "Toast Message", Snackbar.LENGTH_LONG)
.setAction("Click here to activate action", onClickListener)
.setActionTextColor(Color.RED)
.show;
And that is it. No github projects and implementation is very similiar to Toast. I used it in one of my projects and it works great.
You can try SuperToast in this case. It can create toast with button. It has custom duration feature, colourful background, colourful fonts, custom fonts, animated effect. Hope u will enjoy it
Use an alertbox, if you want to add a button :-). Here are some examples
Dialog boxes in Android
Creating a system overlay window (always on top)
This is suggesting that it can be done, I also need buttons in a toast so I still have to make my own implementation. If I find more I will add it to my post