Move About as separate class - android

I'm wasting a lot of time trying to write this:
private void showAbout() {
Dialog dialog = new Dialog(Generator.this);
dialog.setContentView(R.layout.about);
dialog.setTitle(getString(R.string.about));
dialog.setCancelable(true);
try {
TextView tv_version = (TextView) dialog.findViewById(R.id.tv_version);
tv_version.setText("Version number: " + getPackageManager().getPackageInfo(
getPackageName(), 0).versionName);
TextView tv_createdBy = (TextView) dialog
.findViewById(R.id.tv_createdBy);
tv_createdBy.setText(getString(R.string.made_by));
} catch (NameNotFoundException e) {
Log.e(TAG, "showAbout()", e);
} finally {
dialog.show();
}
}
Over to a class in hope to make my code more readable.
I have written it like this:
private void showAbout() {
About about = new About();
about.show();
}
public class About extends Activity {
String TAG = "About";
Dialog dialog;
/**
*
*/
public About() {
dialog = new Dialog(About.this);
}
public void show() {
dialog.setContentView(R.layout.about);
dialog.setTitle(getString(R.string.about));
dialog.setCancelable(true);
try {
TextView tv_version = (TextView) dialog
.findViewById(R.id.tv_version);
tv_version
.setText("Version number: "
+ getPackageManager().getPackageInfo(
getPackageName(), 0).versionName);
TextView tv_createdBy = (TextView) dialog
.findViewById(R.id.tv_createdBy);
tv_createdBy.setText(getString(R.string.made_by));
} catch (NameNotFoundException e) {
Log.e(TAG, "showAbout()", e);
} finally {
dialog.show();
}
}
}
Bt it doesn't work. It seems like it crashes at the creation of the Dialog, but I have no idea how to write it in another way.
Any ideas?

Given the fact that you want to display about in a pop-up way. Then you're doing it wrong. Extending class to Activity will make it an Activity Class (to be used in activity). You should do something like this:
//class level variable
private Dialog formDialog = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
prepareDialog();
}
/**
* We prepare dialog in it's own method so that we can maintain code separation well.
* I believe there is another <em>better</em> solution. But, it work for now.
*/
private void prepareDialog() {
formDialog = new Dialog(ListDataActivity.this);
formDialog.setContentView(R.layout.form);
formDialog.setTitle("Form Buku");
// set dialog width to fill_parent
LayoutParams formDialogParams = formDialog.getWindow().getAttributes();
formDialogParams.width = LayoutParams.FILL_PARENT;
formDialog.getWindow().setAttributes(
(android.view.WindowManager.LayoutParams) formDialogParams);
txtNama = (EditText) formDialog.findViewById(R.id.txtFormNamaPenulis);
txtNama.setText( "about info" );
btnSimpan = (Button) formDialog.findViewById(R.id.btnFormSimpan);
btnBack.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
formDialog.hide();
}
});
}
Note that you will also need to create new .xml layout for this dialog.
Finally, all you have to do to display it is just call formDialog.show();. This answer is extracted and slightly modified from my android tutorial.

Every example I've seen about extending Activity class includes overriding the onCreatemethod. Therefore, you should add the onCreate method and call it's super method by super.onCreate(savedInstanceState);
I also think that a dialog showing should not be an activity. Dialog is always a part of activity.

You could put the code to create and show the "about" dialog in a base Activity, then have your other Activites extend the base one.

Related

Dialog pops up very slow

In my app I have implemented this custom dialog (which has a fairly complex layout) by extending DialogFragment. I expect this dialog to pop up when I click a button in my layout. (Which I have successfully achieved). But the problem is that the dialog shows up in a janky manner.
My custom dialog class:
public class CustomizeDialog extends DialogFragment implements AdapterView.OnItemSelectedListener {
// field declarations go here
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.customize_dialog, null);
builder.setView(view)
.setTitle("Customize")
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setPositiveButton("Let's go!", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction("fromDialog");
intent.putExtra("ratio",getRatio(paperSizeSpinner.getSelectedItem().toString()));
if(isOrientationSpinnerVisible){
intent.putExtra("isCustom",false);
intent.putExtra("orientation",orientationSpinner.getSelectedItem().toString());
} else {
intent.putExtra("isCustom",true);
}
intentProvider.getIntent(intent);
}
});
widthEditText = view.findViewById(R.id.width_et);
heightEditText = view.findViewById(R.id.height_et);
widthEditText.setEnabled(false);
heightEditText.setEnabled(false);
paperSizeSpinner = view.findViewById(R.id.paper_size_spinner);
orientationSpinner = view.findViewById(R.id.orientation_spinner);
// ArrayList for populating paperSize spinner via paperSizeAdapter
ArrayList<String> paperSizes = new ArrayList<>();
paperSizes.add("A0");
paperSizes.add("A1");
paperSizes.add("A2");
paperSizes.add("A3");
paperSizes.add("A4");
paperSizes.add("A5");
paperSizes.add("Custom");
// ArrayList for populating orientation spinner via orientationAdapter
ArrayList<String> orientation = new ArrayList<>();
orientation.add("Portrait");
orientation.add("Landscape");
// arrayAdapters containing arraylists to populate spinners
ArrayAdapter paperSizeAdapter = new ArrayAdapter(getActivity(), android.R.layout.simple_spinner_dropdown_item, paperSizes);
ArrayAdapter orientationAdapter = new ArrayAdapter(getActivity(), android.R.layout.simple_spinner_dropdown_item, orientation);
paperSizeSpinner.setAdapter(paperSizeAdapter);
orientationSpinner.setAdapter(orientationAdapter);
paperSizeSpinner.setSelection(4);
paperSizeSpinner.setOnItemSelectedListener(this);
orientationSpinner.setOnItemSelectedListener(this);
return builder.create();
}
// These are some important complex ui functionalities
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent.getId() == R.id.paper_size_spinner) {
if (position == 6) {
widthEditText.setEnabled(true);
heightEditText.setEnabled(true);
orientationSpinner.setEnabled(false);
isOrientationSpinnerVisible = false;
} else {
widthEditText.setEnabled(false);
heightEditText.setEnabled(false);
orientationSpinner.setEnabled(true);
isOrientationSpinnerVisible = true;
}
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
// interface used to communicate with the parent activity
public interface IntentProvider {
// this method is used to provide the intent to the parent activity
void getIntent(Intent intent);
}
// instantiating the interface object and throwing error if parent activity does not implement this interface
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
try {
intentProvider = (IntentProvider) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement IntentProvider");
}
}
}
MainActivity class:
public class MainActivity extends AppCompatActivity implements CustomizeDialog.IntentProvider {
// field declarations go here
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.image);
// instantiating the dialog
final CustomizeDialog dialog = new CustomizeDialog();
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// showing the dialog on click
dialog.show(getSupportFragmentManager(),"");
}
});
}
// via this method I receive the intent from the dialog
// I know intent might not be the best option for this function but let's let it be here for now
#Override
public void getIntent(Intent intent) {
ratio = intent.getFloatExtra("ratio",3);
isCustom = intent.getBooleanExtra("isCustom",false);
orientation = intent.getStringExtra("orientation");
launchChooser();
}
}
Let me know in the comments if you want the layout code for the dialog.
What I tried:
Implementing threading so that my dialog is ready in a background thread and show it onButtonClick. But this is not allowed in general as any other thread except UI thread aren't supposed to touch UI related events.
Using onCreateView instead of onCreateDialog to inflate the layout directly.
Making the dialog a global variable, initialized it in onCreate and then show the dialog onButtonClick.
Switched to CONSTRAINT LAYOUT
Using an activity as a dialog by setting the dialog theme to the activity in the manifest file.
Launched my app in a device with better hardware than mine.
BUT NOTHING WORKED
What I want:
Why is my dialog janky? and what I need to do to make the dialog pop up faster?
In case anybody wants here's the link to my app repo on github.
AlertDialog and DialogFragment frameworks are slow because they need to some time to do calculations and fragment stuffs. So a solution to this problem is, using the Dialog framework straight away.
Use the Dialog framework's constructor to initialize a Dialog object like this:
Dialog dialog = new Dialog(context, R.style.Theme_AppCompat_Dialog);
// the second parameter is not compulsory and you can use other themes as well
Define the layout and then use dialog.setContentView(R.layout.name_of_layout).
Use dialog.findViewById(R.id.name_of_view) to reference views from the dialog's layout file
And then implement the logic just like anyone would do in an activity class. Find out the best implementation for your use case by reading the official documentation.

Issue about the return value of activityStarting

Today I'm developing an App which can intercept the launch between activities, My key code is:
ActivityManagerNative.getDefault().setActivityController(new InterceptActivityController(), false);
private class InterceptActivityController extends IWeChatActivityController.Stub {
void InterceptActivityController() {}
#Override
public boolean activityStarting(Intent intent, String pkg) {
showDialog();
return false;
}
}
private void showBottomDialog() {
Log.d(TAG, "showBottomDialog");
Dialog bottomDialog = new Dialog(mContext);
View contentView = LayoutInflater.from(this).inflate(android.R.layout.simple_list_item_2, null);
bottomDialog.setContentView(contentView);
ViewGroup.LayoutParams layoutParams = contentView.getLayoutParams();
layoutParams.width = getResources().getDisplayMetrics().widthPixels;
contentView.setLayoutParams(layoutParams);
bottomDialog.getWindow().setGravity(Gravity.BOTTOM);
bottomDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
bottomDialog.show();
}
I defined a Button and planned to start an Activity after clicking it. But now I intercept this action and just show a dialog in the function of activityStarting and then return false, after dismissing this dialog, I click the button again, but nothing works, dialog doesn't show any more, Who knows the reason ? Maybe I think this is a google source bug, but I'm not sure.
You know the Dialogs need to be Shown in a Timely manner. I mean You need the Dialog to be Shown for How Long? When you Start showing a Dialog and Dismiss it, It's Not Destroyed, It's just Dismissed.
Look at the Code below. I wrote this in my own app, It's Safe. Try it and see if you're satisfied with it:
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bottomDialog.show();
new Thread(new Runnable() {
#Override
public void run() {
try {
for (int i = 0; i <= 1200; i++) {
Thread.sleep(100); //The time it takes to update i
if (i = 1200) {
bottomDialog.dismiss();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
You can use AsyncTask as well. Also, I put the whole thing in a Click Listener just to show how it can be used.
The idea is define a showing Time for the Dialog

I want the activity to refresh/redraw after dialog fragment is dismissed.. How can I achieve that?

This is how it looks at first:
This is the dialog fragment that pops when "edit" is pressed and I want The change to be seen in the activity after the dialog fragment is dismissed.
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View view = getActivity().getLayoutInflater().inflate(R.layout.edit_profile_dialog, new LinearLayout(getActivity()), false);
editProfile = (EditText) view.findViewById(R.id.changeProfile);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
setupProgressDialog();
/*get value from Bundle*/
String editValue = getArguments().getString("value", "");
editProfile.setText(editValue);
String title = getArguments().getString("title", "");
builder.setTitle(title);
builder.setView(view);
builder.setCancelable(false);
builder.setPositiveButton("Ok!", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
/*edit the value in shared preference*/
sharedPref = getActivity().getSharedPreferences(getString(R.string.sharedPref), 0);
editor = sharedPref.edit();
editor.putString(getArguments().getString("saved", ""), editProfile.getText().toString());
editor.apply();
ID= sharedPref.getString("id", null);
access_token=sharedPref.getString("token",null);
//Start of AsyncTask after this
If you only need to update the data which user inputs from your dialog you do not have to redraw whole layout.
You can only set the user name to the related textview and dismiss dialog fragment.
TextView yourNameTextView = (TextView)findViewById(R.id.your_textview);
public void setNameToTextView(String name){
yourNameTextView.setText(name);
}
And when user clicks to Ok button you can call:
((YourActivity)getActivity).setText(input);
Good luck.
In your dialog's onClickListener you should be able to invalidate the layout and force a redraw / refresh
check this: How to force an entire layout View refresh?
Thanks to all of you guys trying to help me out.I think I got the answer by doing this:
In my DialogFragment
public class DialogFragmentEditProfile extends DialogFragment {
...
/*Initialize Parent Activity*/
private ChangeProfileActivity cp;
/*Override onAttachMethod */
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
cp = (ChangeProfileActivity) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement FeedbackListener");
}
}
/*create a method to recreate the parent activity*/
public void onButtonPushed(View view) {
cp.recreate();
}
Then onPostExecute() Method of AsyncTask with in the DialogFragment
protected void onPostExecute(String result) {
super.onPostExecute(result);
...
/*Recreate activity after successful update by calling the onButtonPushed() method*/
onButtonPushed(getView());
}
}

Android - Converting an Activity to a popup

Hi I have this code to move from firstActvivity to secondActivity
try {
Class ourClass = Class.forName("com.example.listexample.SecondActivity");
forTransferIntent = new Intent(FirstActivity.this, ourClass);
startActivity(forTransferIntent);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
I want to open my whole class in a popup that contains a button of OK and Cancel and a textfield to extract data from. most popup I have seen are just informative. I am looking for a popup that I can create fields into.
Thanks!
You need to create custom dialog for it (to show activity in a popup)
step 1) create a layout with proper id's.
step 2) use the following code wherever you desire.
LayoutInflater factory = LayoutInflater.from(this);
final View deleteDialogView = factory.inflate(
R.layout.mylayout, null);
final AlertDialog deleteDialog = new AlertDialog.Builder(this).create();
deleteDialog.setView(deleteDialogView);
deleteDialogView.findViewById(R.id.yes).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//your business logic
deleteDialog.dismiss();
}
});
deleteDialogView.findViewById(R.id.no).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
deleteDialog.dismiss();
}
});
deleteDialog.show();
3) in your mylayout use textview/edittext as you wish.(yes button here is your OK button)
hopefully this solves your problem.

how help screen show for one time only in android

in the following code work properly and show help screen when open activity but I want show one time forever,
what can i do?
What should I add in the code?
my code:
public class KhatmMain extends Activity implements OnClickListener{
Context ctx;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = this;
setContentView(R.layout.khatmmain);
showOverLay();
.
.
.
}
private void showOverLay(){
final Dialog dialog = new Dialog(ctx, android.R.style.Theme_Translucent_NoTitleBar);
dialog.setContentView(R.layout.overlay_view);
LinearLayout layout = (LinearLayout) dialog.findViewById(R.id.overlayLayout);
layout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
dialog.dismiss();
}
});
dialog.show();
}
}
You can use SharedPrefereces to set a variable that will check if you've shown the dialog yet to the user or not, here's an example:
SharedPreferences prefs = this.getSharedPreferences("com.you.app", Context.MODE_PRIVATE);
Boolean dialogShown = prefs.getBoolean("dialogShown", false);
Then check if the value of dialogShown is false (you don't need to set it first since it will default to false the way we are calling it), then on the following code we execute some code, only if dialogShown is false, meaning we can do all the dialog stuff inside that conditional:
if(!dialogShown){
//Your show dialog code
prefs.edit().putBoolean("dialogShown",true).commit();
}
So the next time we check for the dialogShown value on the shared preferences it will be true therefor not showing the dialog. I believe this is the most common way of doing it.
There is a solution ..
when application first time start then save the shared preference to the app..
Now each and every time You retrieve the shared preference and check if it is there then move to next screen
Use this code:
public class KhatmMain extends Activity implements OnClickListener{
Context ctx;
Boolean showOneTime = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = this;
setContentView(R.layout.khatmmain);
showOverLay();
.
.
.
}
private void showOverLay(){
if (showOneTime == false) {
return;
}
final Dialog dialog = new Dialog(ctx, android.R.style.Theme_Translucent_NoTitleBar);
dialog.setContentView(R.layout.overlay_view);
LinearLayout layout = (LinearLayout) dialog.findViewById(R.id.overlayLayout);
layout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
dialog.dismiss();
}
});
dialog.show();
showOneTime = false;
}
}

Categories

Resources