I am trying to create a class which can be called from any activity to speak the text from an EditText box. When I run the code I currently have, it plays the alert sound but then fails to play the Text to Speech content. What do I need to change to get the text to play too? I know the activity layout XML code is correct because the Text To Speech code works when it is directly in the activity class. I have looked around for a solution but nowhere else outlines how to do this from a thread context.
I have included my code below:
on AircraftMain.java
View.OnClickListener speakBtnOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View arg0) {
String toSpeak = textToSpeak.getText().toString();
TextToSpeak speak = new TextToSpeak(AircraftMain.this, toSpeak);
speak.run();
}
};
TextToSpeak.java
import android.app.Activity;
import android.media.MediaPlayer;
import android.speech.tts.TextToSpeech;
import java.util.Locale;
public class TextToSpeak implements Runnable {
private Activity activity;
private static String text;
private static TextToSpeech talk;
public TextToSpeak(Activity activity, String toSpeak) {
this.activity = activity;
text = toSpeak;
}
public void run() {
talk = new TextToSpeech(activity, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR) {
talk.setLanguage(Locale.UK);
}
}
});
talk.addEarcon("Attention", "com.kieronmc.aircraftgps", R.raw.warning_beep);
talk.playEarcon("Attention", QUEUE_ADD,null);
talk.setLanguage(Locale.UK);
talk.speak(text, TextToSpeech.QUEUE_ADD, null);
}
}
Try this code, It should work:
1) Create a text to speech Initializer as follows:
public class TextToSpeechInitializer{
private Context context;
private static TextToSpeech talk;
private TextToSpeechIniListener callback;
private Locale locale;
public TextToSpeechInitializer(Context context , Locale locale , TextToSpeechIniListener l) {
this.context = context;
if(l != null) {
callback = l;
}
this.locale = locale;
initialize();
}
private void initialize() {
talk = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
talk.setLanguage(locale); //TODO: Check if locale is available before setting.
callback.onSucces(talk);
}else{
callback.onFailure(talk);
Log.e("TTS","TextToSpeechInitializeError");
}
}
});
}
}
2) The above initializer class calls this interface class to notify the activity below (TTS Success or Failure) :
public interface TextToSpeechIniListener {
public void onSucces(TextToSpeech tts);
public void onFailure(TextToSpeech tts);
}
3) Activity
public class Demo7 extends AppCompatActivity implements TextToSpeechIniListener {
private Button b;
private TextToSpeechInitializer i;
private TextToSpeech talk;
private boolean flag = false;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo7);
i = new TextToSpeechInitializer(this, Locale.UK, this);
b = (Button) findViewById(R.id.b);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(flag) {
talk.addEarcon("Attention", getPackageName(), R.raw.androidcalm);
talk.playEarcon("Attention", QUEUE_ADD, null);
//talk.setLanguage(Locale.UK);
talk.speak("Hello, Testing", QUEUE_ADD, null);
}
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
if(talk != null){
talk.stop();
talk.shutdown();
}
}
#Override
public void onSucces(TextToSpeech tts) {
this.talk = tts;
flag = true;
}
#Override
public void onFailure(TextToSpeech tts) {
flag = false;
finish();
}
}
layout demo7.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/b"
android:text="speak"/>
</LinearLayout>
Related
In my project I have just one Activity that have View.
I think that it has two View that switch the View. The first View is my home that has one Button named "play" . when You click play Button in goes to the second View. Second View is my game.
And now my problem is that when I want to use onBackPressed() method in the second View, it closes the Activity. and onBackPressed() method do the same in both View.
How to handle onBackPressed() method in second View that return to the first View.
How to switch the View in onBackPressed()?
I am new with Android and now I really confused.
any suggestion? or any key word to search to solve my problem.
here is my code:
public class PTPlayer extends Cocos2dxActivity {
static Splash splash;
public static AppList appList;
static Noti_Queue noti_queue;
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.v("----------", "onActivityResult: request: " + requestCode + " result: " + resultCode);
if (requestCode == PTServicesBridge.RC_SIGN_IN) {
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (splash == null) {
splash = new Splash(this);
splash.set_identity("1");
}
if (appList == null) {
appList = new AppList(this);
appList.set_identity("1");
}
if (noti_queue == null) {
noti_queue = new Noti_Queue(this);
noti_queue.set_identity("1");
}
}
#Override
public void onNativeInit() {
initBridges();
}
private void initBridges() {
PTStoreBridge.initBridge(this);
PTServicesBridge.initBridge(this, getString(R.string.app_id));
if (PTJniHelper.isAdNetworkActive("kChartboost")) {
PTAdChartboostBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kRevMob")) {
PTAdRevMobBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kAdMob") || PTJniHelper.isAdNetworkActive("kFacebook")) {
PTAdAdMobBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kAppLovin")) {
PTAdAppLovinBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kLeadBolt")) {
PTAdLeadBoltBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kVungle")) {
PTAdVungleBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kPlayhaven")) {
PTAdUpsightBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kMoPub")) {
PTAdMoPubBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kFacebook")) {
PTAdFacebookBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kHeyzap")) {
PTAdHeyzapBridge.initBridge(this);
}
}
#Override
public Cocos2dxGLSurfaceView onCreateView() {
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
glSurfaceView.setEGLConfigChooser(8, 8, 8, 0, 0, 0);
return glSurfaceView;
}
static {
System.loadLibrary("player");
}
#Override
protected void onResume() {
super.onResume();
if (PTJniHelper.isAdNetworkActive("kChartboost")) {
PTAdChartboostBridge.onResume(this);
}
}
#Override
protected void onStart() {
super.onStart();
if (PTJniHelper.isAdNetworkActive("kChartboost")) {
PTAdChartboostBridge.onStart(this);
}
}
#Override
protected void onStop() {
super.onStop();
if (PTJniHelper.isAdNetworkActive("kChartboost")) {
PTAdChartboostBridge.onStop(this);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
public void onBackPressed() {
splash.Display();
splash = null;
super.onBackPressed();
}
}
here i think that in my second view:
public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelperListener {
// ===========================================================
// Constants
// ===========================================================
private static final String TAG = Cocos2dxActivity.class.getSimpleName();
// ===========================================================
// Fields
// ===========================================================
private Cocos2dxGLSurfaceView mGLSurfaceView;
private Cocos2dxHandler mHandler;
private static Context sContext = null;
public static Context getContext() {
return sContext;
}
// ===========================================================
// Constructors
// ===========================================================
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sContext = this;
this.mHandler = new Cocos2dxHandler(this);
this.init();
Cocos2dxHelper.init(this, this);
}
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
#Override
protected void onResume() {
super.onResume();
Cocos2dxHelper.onResume();
this.mGLSurfaceView.onResume();
}
#Override
protected void onPause() {
super.onPause();
Cocos2dxHelper.onPause();
this.mGLSurfaceView.onPause();
}
#Override
public void showDialog(final String pTitle, final String pMessage) {
Message msg = new Message();
msg.what = Cocos2dxHandler.HANDLER_SHOW_DIALOG;
msg.obj = new Cocos2dxHandler.DialogMessage(pTitle, pMessage);
this.mHandler.sendMessage(msg);
}
#Override
public void showEditTextDialog(final String pTitle, final String pContent, final int pInputMode, final int pInputFlag, final int pReturnType, final int pMaxLength) {
Message msg = new Message();
msg.what = Cocos2dxHandler.HANDLER_SHOW_EDITBOX_DIALOG;
msg.obj = new Cocos2dxHandler.EditBoxMessage(pTitle, pContent, pInputMode, pInputFlag, pReturnType, pMaxLength);
this.mHandler.sendMessage(msg);
}
#Override
public void runOnGLThread(final Runnable pRunnable) {
this.mGLSurfaceView.queueEvent(pRunnable);
}
// ===========================================================
// Methods
// ===========================================================
public void init() {
// FrameLayout
ViewGroup.LayoutParams framelayout_params =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
FrameLayout framelayout = new FrameLayout(this);
framelayout.setLayoutParams(framelayout_params);
// Cocos2dxEditText layout
ViewGroup.LayoutParams edittext_layout_params =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
this.mGLSurfaceView = this.onCreateView();
// Switch to supported OpenGL (ARGB888) mode on emulator
if (isAndroidEmulator())
this.mGLSurfaceView.setEGLConfigChooser(8 , 8, 8, 8, 16, 0);
this.mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer());
RelativeLayout relativeLayout = new RelativeLayout(getApplicationContext());
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
relativeLayout.setLayoutParams(params);
//AdView adad = new AdView(this);
ClickBanner_CLickYab_Holder adad = new ClickBanner_CLickYab_Holder(this);
RelativeLayout.LayoutParams adad_params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
adad_params.addRule(RelativeLayout.CENTER_HORIZONTAL);
adad_params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
// adad.setToken(getString(R.string.adad_token));
adad.setLayoutParams(adad_params);
Button myButton = new Button(this);
myButton.setBackgroundResource(R.drawable.more);
RelativeLayout.LayoutParams adad_params1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
adad_params1.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
adad_params1.addRule(RelativeLayout.ALIGN_PARENT_TOP);
myButton.setLayoutParams(adad_params1);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
PTPlayer.appList.Display();
}
});
Button myButton1 = new Button(this);
myButton1.setBackgroundResource(R.drawable.more);
RelativeLayout.LayoutParams adad_params2 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
adad_params2.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
adad_params2.addRule(RelativeLayout.ALIGN_PARENT_TOP);
myButton1.setLayoutParams(adad_params2);
myButton1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
PTPlayer.appList.Display();
}
});
relativeLayout.addView(this.mGLSurfaceView);
relativeLayout.addView(adad);
relativeLayout.addView(myButton);
relativeLayout.addView(myButton1);
ClickBanner_CLickYab_Holder.setTestMode();
setContentView(relativeLayout);
}
public Cocos2dxGLSurfaceView onCreateView() {
return new Cocos2dxGLSurfaceView(this);
}
private final static boolean isAndroidEmulator() {
String model = Build.MODEL;
Log.d(TAG, "model=" + model);
String product = Build.PRODUCT;
Log.d(TAG, "product=" + product);
boolean isEmulator = false;
if (product != null) {
isEmulator = product.equals("sdk") || product.contains("_sdk") || product.contains("sdk_");
}
Log.d(TAG, "isEmulator=" + isEmulator);
return isEmulator;
}
}
you must use of Override Method for when back button pressed
if you want to stay on currnt activity use like this
#Override
public void onBackPressed() {
return;
}
if you want to use double click to exit and one click to stay you can use like this
first define a variable for double click
boolean doubleBackToExit = false;
and the Override backbutton method
#Override
public void onBackPressed() {
if (doubleBackToExit) {
//on double back button pressed
return;
}
this.doubleBackToExit = true;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExit=false;
}
}, 2000);
}
Then do this.
#Override
public void onBackPressed() {
super.onBackPressed();
Intent intent = new Intent(MainActivityPhase2.this, GlobalSearch.class);
startActivity(intent);
finish();
}
Just don't call the super.onBackPressed() everytime.
#Override
public void onBackPressed() {
if (isFirstView()) {
super.onBackPressed();
} else {
switchToFirstView();
}
Call in only when there isn't any last view available. Or where you want to close the App. The code will finish your activity when you are on the first activity. And switch to first activity if you are on second activity.
Just replace my methods as per your code.
Overriding onBackPressed() of the activity and provide your screen where you want to go.
onBackpressed() check which is the current view you are showing and according to move to the first view.
in your second class Cocos2dxActivity, place this code.
#Override
public void onBackPressed() {
this.finish();
}
If you have just one activity with two View you can use Fragments.
Using Fragments, Activity.OnBackPressed() will remove last fragment in the stack and you can resolve your problem.
So, in the activity you have to put a container in xml layout file:
<FrameLayout android:id="#+id/container" android:layout_width="match_parent"
android:clickable="true" android:layout_height="match_parent"/>
In the Activity java file:
getFragmentManager().beginTransaction()
.add(R.id.container,new YourHomeFragment())
.commit();
So to add second Fragment you can use this code:
getFragmentManager().beginTransaction()
.add(R.id.container,new YourPlayFragment())
.addToBackStack("YourPlayFragment") //string what you want
.commit();
Pay attention: you can call this code or in YourHomeFragment class (into button clickListener) or in your Activity (using a callback system). For example:
In YourHomeFragment -->
playButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getFragmentManager().beginTransaction()
.add(R.id.container,new YourPlayFragment())
.addToBackStack("YourPlayFragment") //string what you want
.commit();
}
});
In this way, you have to declare two layout xml file for fragments and one for Activity.
List of java and relative xml files:
MainActivity.java
activity_main.xml
YourHomeFragment.java
fragment_your_home.xml <-- insert here your first View
YourPlayFragment.java
fragment_your_play.xml <-- play view
I have Android module library which will create the Touch Keypad UI and set event listener for done and backbutton.
Also have main activity with implement eventCallback interface
MainActivity.java (Appication)
public class MainActivity extends AppCompatActivity implements eventCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View v = new touchkey(this);
setContentView(v);
}
#Override
public void onClick() {
Log.i("test","complete");
Toast.makeText(this, "this is my Toast message!!! =)",
Toast.LENGTH_LONG).show();
}
}
eventCallback.java (Android Module Library)
public interface eventCallback {
void onClick();
}
touchkey.java (Android Module Library)
public class touchkey extends RelativeLayout{
private static touchkey INSTANCE;
TextView bclear;
ImageView bdone;
eventCallback eventCall;
public touchkey(Context context) {
super(context);
initialize(context);
}
public touchkey(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context);
}
public void test() {
Log.i("test","test");
}
private void initialize(Context context) {
inflate(context, R.layout.touchkey, this);
bclear = (TextView) findViewById(R.id.anti_theft_t9_key_clear);
bdone = (ImageView) findViewById(R.id.anti_theft_t9_key_done);
bdone.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (eventCall != null) {
eventCall.onClick();
}
}
});
backButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
}
but iam getting nullpointer exception on the touchkey.java
eventCall.onClick(); (eventCall is null)
I dont know where i am doing things wrong. can anybody help on this. Requirement: i need to handle the click event happening on the Library in Main Activity
You must create setter for eventCall (in touchkey.java):
public void setEventCall(eventCallback eventCall) {
this.eventCall = eventCall;
}
And, use it (in MainActivity):
View v = new touchkey(this);
setContentView(v);
((touchkey) v).setEventCall(this);
I have a problem with code. I have two classes: MainActivity where i checking if sensor (in this case light sensor) is available and if yes - i try to get date from sensor from another class LightSensor, but result is always null. I think that i'm doing something wrong with listener but i don't know what.. and i'm sitting on this couple of hours and still nothing.. If you have any idea, please write and help me.
MainActivity class:
`public class MainActivity extends Activity implements EventListener {
SensorManager mSensorManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView wyswietl = (TextView)findViewById(R.id.res);
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
LightSensor mLightSensor = new LightSensor(getBaseContext());
if (mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) != null){
//mLightSensor.register();
String newLux = mLightSensor.getLux();
wyswietl.setText("Light level: " + newLux);
}
else{
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}`
and in MainActivioty class i don't know it argument in constructor :
LightSensor mLightSensor = new LightSensor(getBaseContext()); is good...
LightSensor class:
`public class LightSensor implements SensorEventListener {
public SensorManager mSensorManagerx;
public Sensor lightManager;
public String lux;
Context context;
public LightSensor(Context context){
//public void onCreateLight(Context context){
this.context = context;
mSensorManagerx = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
lightManager = mSensorManagerx.getDefaultSensor(Sensor.TYPE_LIGHT);
}
public void register(){
mSensorManagerx.registerListener(this, lightManager, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
lux = Float.toString(event.values[0]);
}
public String getLux(){
return lux;
}
public void unregister(){
mSensorManagerx.unregisterListener(this);
}
}`
You should not use a getter for this purpose, because the value your getting will be initialized after a unknown time. So it could still be null when you're calling the getLux method.
What you should do is use a listener pattern. I have changed your code a bit to give you an example implementation.
LightSensor:
public class LightSensor implements SensorEventListener {
public static interface LightSensorListener {
abstract void onLightSensorChanged(String lux);
}
private LightSensorListener listener;
private SensorManager mSensorManagerx;
private Sensor lightManager;
public LightSensor(Context context) {
mSensorManagerx = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
lightManager = mSensorManagerx.getDefaultSensor(Sensor.TYPE_LIGHT);
}
public void setListener(LightSensorListener listener) {
this.listener = listener;
}
public boolean register() {
return mSensorManagerx.registerListener(this, lightManager, SensorManager.SENSOR_DELAY_UI);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
public void onSensorChanged(SensorEvent event) {
if (listener != null) {
listener.onLightSensorChanged(Float.toString(event.values[0]));
}
}
public void unregister() {
mSensorManagerx.unregisterListener(this);
}
}
Activity:
public class ActivityLightSensor extends Activity implements LightSensorListener {
private TextView text;
private LightSensor mLightSensor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView)findViewById(R.id.test);
mLightSensor = new LightSensor(getBaseContext());
mLightSensor.setListener(this);
}
#Override
public void onLightSensorChanged(String lux){
text.setText("Light level: " + lux);
}
#Override
protected void onResume() {
super.onStart();
if(!mLightSensor.register()){
Toast.makeText(this, "Light sensor not supported!", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onPause() {
super.onStop();
mLightSensor.unregister();
}
}
onSensorChanged event is not called just after you created listener. It is called after something will change sensot value, then it will be called. So you should implement some callback, or, as for me, better would be to implement SensorEventListener in your activity, then just in onSensorChanged event method call
wyswietl.setText("Light level: " + newLux);
My app shows many custom dialog like Yes/No or Accept/Cancel decissions and, while I was coding, I realized that there are so much code repeated, following the same schema.
I want to build a general class but I don't know how to do it or, more exactly, the correct way that I have to do it(interfaces, abstract classes, inheritance, static classes, ...)
This is my current class:
public class DialogTwoOptions extends Dialog {
TextView title_tv;
// Button yes_btn, no_btn;
public DialogTwoOptions(Context context)
{
super(context);
setContentView(R.layout.dialogo_sino); // a simple layout with a TextView and Two Buttons
title_tv = (TextView) findViewById(R.id.dialogo_titulo_sino);
// yes_btn = (Button) findViewById(R.id.dialogo_aceptar);
// no_btn = (Button) findViewById(R.id.dialogo_cancelar);
View v = getWindow().getDecorView();
v.setBackgroundResource(android.R.color.transparent);
}
public void quitDialog(View v) {
if (isShowing()) dismiss();
}
public void setTitle(String title) {
title_tv.setText(title);
}
}
And this is what I am doing when I need to use this class:
final DialogTwoOptions dialog = new DialogTwoOptions(this);
Button yes = (Button) dialog.findViewById(R.id.dialog_yes_btn);
Button no = (Button) dialog.findViewById(R.id.dialog_no_btn);
yes.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v) {
dialog.dismiss();
// Do something
}
});
no.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v) {
dialog.dismiss();
// Do something
}
});
dialog.show();
I am sure that it is improvable, but how could you do this?
Thanks
First create an Base DialogFragment to keep hold of the instance of the Activity. So when the Dialog is attached to the Activity , you will know the instance of the Activity which created it.
public abstract class BaseDialogFragment<T> extends DialogFragment {
private T mActivityInstance;
public final T getActivityInstance() {
return mActivityInstance;
}
#Override
public void onAttach(Activity activity) {
mActivityInstance = (T) activity;
super.onAttach(activity);
}
#Override
public void onDetach() {
super.onDetach();
mActivityInstance = null;
}
}
Then, create a GeneralDialogFragment which extends the BaseDialogFragment
public class GeneralDialogFragment extends BaseDialogFragment<GeneralDialogFragment.OnDialogFragmentClickListener> {
// interface to handle the dialog click back to the Activity
public interface OnDialogFragmentClickListener {
public void onOkClicked(GeneralDialogFragment dialog);
public void onCancelClicked(GeneralDialogFragment dialog);
}
// Create an instance of the Dialog with the input
public static GeneralDialogFragment newInstance(String title, String message) {
GeneralDialogFragment frag = new GeneralDialogFragment();
Bundle args = new Bundle();
args.putString("title", title);
args.putString("msg", message);
frag.setArguments(args);
return frag;
}
// Create a Dialog using default AlertDialog builder , if not inflate custom view in onCreateView
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setTitle(getArguments().getString("title"))
.setMessage(getArguments().getString("message"))
.setCancelable(false)
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Positive button clicked
getActivityInstance().onOkClicked(GeneralDialogFragment.this);
}
}
)
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// negative button clicked
getActivityInstance().onCancelClicked(GeneralDialogFragment.this);
}
}
)
.create();
}
}
If you need to use your own custom layout for dialog,then inflate a layout in onCreateView and remove onCreateDialog . But Add the click listeners in onCreateView like i explained in onCreateDialog
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_dialog, container, false);
return view;
}
Then , In your Activity need to implement an interface to handle the action in dialog
public class TryMeActivity extends
FragmentActivity implements GeneralDialogFragment.OnDialogFragmentClickListener {
#Override
public void onOkClicked(GeneralDialogFragment dialog) {
// do your stuff
}
#Override
public void onCancelClicked(GeneralDialogFragment dialog) {
// do your stuff
}
}
Finally, Show the Dialog from your Activity when required, like this
GeneralDialogFragment generalDialogFragment =
GeneralDialogFragment.newInstance("title", "message");
generalDialogFragment.show(getSupportFragmentManager(),"dialog");
Hope this helps. I am sure this approach is one of the optimized way, but there could be also different approaches .
I faced a problem like you. And all in stackoverflow does not meet what I want. So I create my own Dialog Class and it can use like AlertDialog.Builder class.
In my dialogxml.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/drconner">
<LinearLayout
android:id="#+id/under"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/malertTitle"
android:layout_width="match_parent"
android:layout_height="50dp"
android:padding="5dp"
android:textSize="25sp"
android:textColor="#ffffff"
android:drawablePadding="2dp"
android:background="#color/colorPrimaryDark"
/>
<TextView
android:id="#+id/aleartMessage"
android:layout_width="match_parent"
android:layout_height="75dp"
android:padding="5dp"
android:textSize="18sp"
android:textColor="#color/colorAccent"/>
</LinearLayout>
<LinearLayout
android:layout_below="#+id/under"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
android:orientation="horizontal">
<Button
android:id="#+id/aleartYes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:id="#+id/aleartNo"
android:layout_marginLeft="30dp"
android:layout_marginStart="30dp"
android:layout_marginRight="3dp"
android:layout_marginEnd="3dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</RelativeLayout>
For Dialog Shape I create just simple shape xml - drconner.xml
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="5dp"/>
<stroke android:color="#color/colorPrimaryDark" android:width="2dp"/>
</shape>
For custom Alert I create Alear.java as follow
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
/**
* Created by sanyatihan on 27-Dec-16.
*/
public class Alert extends Dialog {
private String message;
private String title;
private String btYesText;
private String btNoText;
private int icon=0;
private View.OnClickListener btYesListener=null;
private View.OnClickListener btNoListener=null;
public Alert(Context context) {
super(context);
}
public Alert(Context context, int themeResId) {
super(context, themeResId);
}
protected Alert(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.dialogxml);
TextView tv = (TextView) findViewById(R.id.malertTitle);
tv.setCompoundDrawablesWithIntrinsicBounds(icon,0,0,0);
tv.setText(getTitle());
TextView tvmessage = (TextView) findViewById(R.id.aleartMessage);
tvmessage.setText(getMessage());
Button btYes = (Button) findViewById(R.id.aleartYes);
Button btNo = (Button) findViewById(R.id.aleartNo);
btYes.setText(btYesText);
btNo.setText(btNoText);
btYes.setOnClickListener(btYesListener);
btNo.setOnClickListener(btNoListener);
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void setIcon(int icon) {
this.icon = icon;
}
public int getIcon() {
return icon;
}
public void setPositveButton(String yes, View.OnClickListener onClickListener) {
dismiss();
this.btYesText = yes;
this.btYesListener = onClickListener;
}
public void setNegativeButton(String no, View.OnClickListener onClickListener) {
dismiss();
this.btNoText = no;
this.btNoListener = onClickListener;
}
}
To use this Alert class, just simple as the use of AlertDialog.Builder class
for example :
final Alert mAlert = new Alert(this);
mAlert.setTitle("This is Error Warning");
mAlert.setIcon(android.R.drawable.ic_dialog_alert);
mAlert.setMessage("Do you want to delete?");
mAlert.setPositveButton("Yes", new View.OnClickListener() {
#Override
public void onClick(View view) {
mAlert.dismiss();
//Do want you want
}
});
mAlert.setNegativeButton("No", new View.OnClickListener() {
#Override
public void onClick(View view) {
mAlert.dismiss();
//Do want you want
}
});
mAlert.show();
The main thing is you should call dismiss() function in your onClick. I hope this may help to you. And let me know if this is what you want or not. You can change the layout as you want in dialogxml.xml.
I have been using this for some time.
Calling the alert dialog inside an activity, where alertDialog is a static function in a class called Misc:
Misc.alertDlg(this, "Confirm", "Delete the file?", "Yes", null, "Cancel",
(DialogInterface dialog, int which) -> {
if(which == Misc.BTN_POS)
deleteYourFile()
});
}
And the alert dialog function (a static function in a class called Misc:
static public void alertDlg(Context context, String title, String msg, String btnPos, String btnNeutral, String btnNeg, DialogInterface.OnClickListener ocListener) {
Builder db = new AlertDialog.Builder(context);
db.setTitle(title);
db.setMessage(msg);
if (btnPos != null) db.setPositiveButton(btnPos, ocListener);
if (btnNeutral != null) db.setNeutralButton(btnNeutral, ocListener);
if (btnNeg != null) db.setNegativeButton(btnNeg, ocListener);
db.setIcon(android.R.drawable.ic_dialog_alert);
db.show();
}
But I have just recently converted it to kotlin.
Calling the alert dialog (in Kotlin):
Misc.alertDlg(this, "Confirm", "Delete the file?", "Yes", null, "Cancel"){
which-> if(which == Misc.BTN_POS) deleteYourFile()
}
And the alert dialog function (a function in an object called Misc):
fun alertDlg(context: Context, title: String, msg: String, btnNeg: String?, btnNeutral: String?, btnPos: String?,
onClickCallback: (which: Int) -> Unit) {
val ocListener = DialogInterface.OnClickListener() {dialog, which ->
onClickCallback(which)
}
val db = AlertDialog.Builder(context)
db.setTitle(title)
db.setMessage(msg)
if (btnPos != null) db.setPositiveButton(btnPos, ocListener)
if (btnNeutral != null) db.setNeutralButton(btnNeutral, ocListener)
if (btnNeg != null) db.setNegativeButton(btnNeg, ocListener)
db.setIcon(android.R.drawable.ic_dialog_alert)
db.show()
}
I have also been using a similar method to show a text input dialog.
You can use AlertDialog and AlertDialog.Builder.
new AlertDialog.Builder(context)
.setTitle("some_title")
.setMessge("some_message")
.setNegativeButton("No", null)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(int which) {
// do some action
}
})
.show();
try below code:
calling way
new CustomDialog().makeDialog(Activity.this,"pass value from diffrent-2 ");
class CustomDialog
public class CustomDialog
{
public void makeDialog(Context con, String value)
{
final DialogTwoOptions dialog = new DialogTwoOptions(con);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.ur_xml);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
// set the custom dialog components - text, image
// and button
dialog.setCanceledOnTouchOutside(false);
Button yes = (Button) dialog.findViewById(R.id.dialog_yes_btn);
Button no = (Button) dialog.findViewById(R.id.dialog_no_btn);
yes.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
dialog.dismiss();
// Do something
if (value.equals("1"))
{
}
else if (value.equals("1"))
{
}
// do more condition
}
});
no.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
dialog.dismiss();
// Do something
if (value.equals("1"))
{
}
else if (value.equals("1"))
{
}
// do more condition
}
});
dialog.show();
}
}
package com.example.jojo.gridview;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;
public class DialogClass extends Dialog {
Bitmap b;
String n;
public DialogClass(Context context,Bitmap img,String name) {
super(context);
b=img;
n=name;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.dialog_style);
ImageView image= (ImageView) findViewById(R.id.imageView2);
TextView text= (TextView) findViewById(R.id.textView2);
image.setImageBitmap(b);
text.setText(n);
}
}
I am trying to make listener interface between two activities Act1 and Act2. Act1 will start Act2. If there is some event occurred in Act2, it will inform it to Act1. Problem is that I am starting new activity using Intent, so how Act1 will assign itself as listener to Act2's interface?
Act1.java
public class Act1 extends ActionBarActivity implements
ActionBar.OnNavigationListener {
ActionBar actionbar;
Intent pizzaIntent;
boolean visibleFirstTime = true;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menutab);
//set actionbar here
}
#Override
public boolean onNavigationItemSelected(int arg0, long arg1)// item pos,
// itemid
{
switch (arg0) {
case 0:
if(this.visibleFirstTime == false)
{
if(pizzaIntent == null)
{
pizzaIntent = new Intent(this,Act2.class);
//how to call setChangeListener?
}
startActivity(pizzaIntent);
}
else
this.visibleFirstTime = false;
break;
case 1:
System.out.println("selected: " + arg0);
break;
case 2:
System.out.println("selected: " + arg0);
break;
case 3:
System.out.println("selected: " + arg0);
break;
default:
break;
}
return true;
}
}
Act2.java
public class Act2 extends Activity {
selectionChangeListener listener;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pizza_slice_selection);
}
public void setChangeListener(selectionChangeListener listener)
{
this.listener = listener;
}
private interface selectionChangeListener
{
public void selectionMadeAtIndex(int index);
}
}
Note: Please don't suggest me to use fragments. I want to use activities currently.
I would suggest to create a model class. Let me give you an example:
Model class:
public class CustomModel {
public interface OnCustomStateListener {
void stateChanged();
}
private static CustomModel mInstance;
private OnCustomStateListener mListener;
private boolean mState;
private CustomModel() {}
public static CustomModel getInstance() {
if(mInstance == null) {
mInstance = new CustomModel();
}
return mInstance;
}
public void setListener(OnCustomStateListener listener) {
mListener = listener;
}
public void changeState(boolean state) {
if(mListener != null) {
mState = state;
notifyStateChange();
}
}
public boolean getState() {
return mState;
}
private void notifyStateChange() {
mListener.stateChanged();
}
}
And here's how you would use this:
// Imports
public class MainActivity extends Activity implements OnCustomStateListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CustomModel.getInstance().setListener(this);
boolean modelState = CustomModel.getInstance().getState();
Log.d(TAG, "Current state: " + String.valueOf(modelState));
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
}
#Override
public void stateChanged() {
boolean modelState = CustomModel.getInstance().getState();
Log.d(TAG, "MainActivity says: Model state changed: " +
String.valueOf(modelState));
}
}
Changing the member state in second activity:
// Imports
public class SecondActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CustomModel.getInstance().changeState(true);
}
}
LogCat output:
Current state: false
MainActivity says: Model state changed: true
Have you considered using LocalBroadcastManager?
In Act1's onCreate:
act2InitReceiver= new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
// do your listener event stuff
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(act2InitReceiver, new IntentFilter("activity-2-initialized"));
In Act1's onDestroy:
LocalBroadcastManager.getInstance(this).unregisterReceiver(act2InitReceiver);
In Act2's onCreate:
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("activity-2-initialized"));
Give me a comment if the code doesn't compile, I'm writing it by hand.
The best, shortest and the easiest way to do this is to use static variables, like this:
class Main extends Activity {
static String message = "Hi";
}
class Another extends Activity {
public onCreate() {
Log.i(Main.message); // implementation of the message, 'Hi'
}
}