I have some listView on my mainActivity - the listView contain names of people.
I want to make some window popup that will contain all 'more info' about someone that was click on him.
I mean that if the user click on some person form this list - i want to popup some window above the mainActivity and show more information about that person that was the one who the user click on him
I can't find a way to create the popup window
( AlertDialog is not what i need .. i need dialog that i can edit fully and set data as i want )
yes it's possible
extend Dialog class and make a custom view
public class MyDialog extends Dialog {
YourParams yourParams;
Context context;
public MyDialog(Context context, YourParams yourParams) {
super(context);
this.context = context;
this.yourParams = yourParams;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_sample);
//
// some code ...
//
}
}
then call it like this
MyDialog dialog = new MyDialog(MainActivity.this,yourParams);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.show();
To follow material design guidelines, I think you can make use of Bottom Sheets, like here on that middle screen:
There are many libraries that will help you with this, for example https://github.com/Flipboard/bottomsheet
I want to show a custom dialog box when I start my first activity without using a button. I try to search but I'm not finding the proper solution what I really want to do. Many of them are using onClick Listener to achieve that the scenario. Below image is showing an activity with a dialog box, that's what I'm looking for but without using onClick Listener.
How can we implement without using onClick Listener?
Any code contained in a click listener also works elsewhere in the class (unless you use the view that's clicked)
Create the dialog in onCreate. It will open immediately when the activity is started
In your main Activity oncreate method:
createCustomizeDialog();
now create this method outside of oncreate:
private void createCustomizeDialog() {
final AlertDialog.Builder builder=new AlertDialog.Builder(this);
LayoutInflater inflater = getActivity().getLayoutInflater();
#SuppressLint("InflateParams") final View alertLayout = inflater.inflate(R.layout.customize_dialog, null);
Button submit=(Button)alertLayout.findViewById(R.id.sButton);
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
builder.setView(alertLayout);
alertDialog=builder.create();
//noinspection ConstantConditions
alertDialog.show();
}
Just try this way
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("TADAAAA!").create().show();
}
If you want to show the dialog only for the FIRST launch of this activity, you should put the code for your dialog in onCreate method of this activity, if it should be done for EVERY launch of this activity - then in onStart() method.
I use the ViewPager from the compatibility pack to page fragments.
I want to have a background service which serves the fragments with data. Therefore I use a "normal java class" to update (for example) a TextView in such a fragment:
public class Updater {
private Activity mActivity=null;
private TextView tv = null;
private Context mContext;
private View mInflatedMenu =null;
public Updater (Activity _activity, Context _context, View inflatedMenu) {
mActivity = _activity;
mContext = _context;
mInflatedMenu = inflatedMenu;
}
public void updateTextView (String _text) {
tv = (TextView) mInflatedMenu.findViewById(R.id.tvFragment1Updater);
tv.setText(_text);
Toast.makeText(mContext, tv.getText(), Toast.LENGTH_SHORT).show();
}
}
The Toast says, that the TextView has the value of the parameter _text. That's okay!
The problem: On the screen the original value of the TextView hasn't changed to _text.
I think I've tried all kinds of invalidate(). What I'm doing wrong? How would you update your fragment "views" in a ViewPager?
You need to save the toast instance, when you are changing the vlaue of _text, you neen to hide the old toast and create a new one.
I have an activity with a spinner, and I was wondering if it is possible to close the spinner programmatically, if the user has opened it.
The whole story is that in the background I am running a process on a separate thread. When the process has finished, I invoke a Handler on the main activity and, depending on the outcome, I perform some tasks. It is then that I want to close the spinner, it the user has opened it.
The spinner is in the main.xml layout:
<Spinner android:id="#+id/birthPlaceSpinner" android:layout_weight="1"
android:layout_height="wrap_content" android:prompt="#string/select"
android:layout_width="fill_parent" />
and this is the Handler:
private class BirthplaceChangedHandler extends Handler {
#Override
public void handleMessage(Message msg) {
String placeFilterStr = birthPlaceFilterText.getText().toString();
if ("".equals(placeFilterStr) || placeFilterStr == null || validNewAddresses.isEmpty()) {
birthPlaceSpinner.setEnabled(false);
hideGeoLocationInformation();
} else {
birthPlaceSpinner.setEnabled(true);
}
adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.multiline_spinner_dropdown_item, validNewAddressesStr)
birthPlaceSpinner.setAdapter(adapter);
}
}
Cheers!
public static void hideSpinnerDropDown(Spinner spinner) {
try {
Method method = Spinner.class.getDeclaredMethod("onDetachedFromWindow");
method.setAccessible(true);
method.invoke(spinner);
} catch (Exception e) {
e.printStackTrace();
}
}
This works for me:
class SomeAdapter extends BaseAdapter implements SpinnerAdapter {
//......
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
//......
}
view.setOnClickListener(new ItemOnClickListener(parent));
return view;
}
//.....
}
and the click listener:
class ItemOnClickListener implements View.OnClickListener {
private View _parent;
public ItemOnClickListener(ViewGroup parent) {
_parent = parent;
}
#Override
public void onClick(View view) {
//.......
// close the dropdown
View root = _parent.getRootView();
root.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
root.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));
}
}
Well its a little complicated than I thought.
I am adding the step by step details here. Try to follow it. I was able to achieve this in api level 10.
And this solution assumes that you are supposed to close the prompt dialog programatically when the user clicks on Home Button or If you had to move to next activity without user interaction
The first step is to create a Custom Spinner by extending Spinner Class.
Let's say, I have created a class called CustomSpinner in the package com.bts.sampleapp
My CustomSpinner class looks like this,
package com.bts.sampleapp;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Spinner;
public class CustomSpinner extends Spinner{
Context context=null;
public CustomSpinner(Context context) {
super(context);
this.context=context;
}
public CustomSpinner(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomSpinner(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
}
}
Now in your Xml file, replace Spinner element by this custom spinner,
<com.bts.sampleapp.CustomSpinner
android:id="#+id/spin"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
The next step is to initialize and set adapter to this spinner in your Activity class,
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CustomSpinner spin=null;
spin=(CustomSpinner)findViewById(R.id.spin);
spin.setAdapter(spinnerAdapter); //you can set your adapter here.
}
The final step is to close the dialog when the user clicks on HomeButton or When the Activity moves to background. To do this, we override the onPause() like this,
#Override
protected void onPause() {
Log.i("Life Cycle", "onPause");
spin.onDetachedFromWindow();
super.onPause();
}
Now within the onPause() call the method spin.onDetachedFromWindow(); which does the job of closing the prompt dialog for you.
Now that being said, calling spin.onDetachedFromWindow(); from anywhere in your Activity should help you to close the spinner programatically. So if this is what you want, then remove the onpause().
I don't see a way to accomplish that -- there is no method on Spinner to close it. The "open" part of a Spinner is an AlertDialog on Android 1.x and 2.x, and I'm not completely sure how it is implemented on Honeycomb when using the holographic theme.
The only workaround would be to clone the source for Spinner and add in some code yourself to dismiss the dialog. But, again, it would not work on Honeycomb or higher until you can see and clone that code as well.
Beyond that, I would think that what you want is poor UX. If the user opened the Spinner, they are most likely actively examining the Spinner's contents and making a selection. Yanking that out from under their finger will confuse them, at best. Please consider an alternative approach.
Also, don't use getApplicationContext() unless you know why you are using getApplicationContext(). You do not need or even want getApplicationContext() when creating an ArrayAdapter.
I think you should scrap your use of Spinner and instead use an ImageView with a Frame Animation (i.e. <animation-list>) to create your own spinner. You just set the ImageView's background to be your Frame Animation drawable.
Then you can easily do something like this to start and stop it.
You would like to close your spinners from anywhere. Key injection for BACK pressed is the good solution but, here you are closing all the views at once.
How about setPressed(false)?
Link:
Close Spinners dropdown when two among all in a groupview are clicked simultaneously
Otherwise:
Try to make the Spinner focusable and focusableInTouchMode, and use clearFocus()
on it. Try to focus on the view below it using requestFocus() method.
Check if the spinner drop-down closes
Use the clearFocus() to close the spinner programitically
spinner.clearFocus();
Add clearfocus() in code.
Spinner spinner = (Spinner) findViewById(R.id.spinner);
spinner.clearFocus();
Use transparent background in xml
android:background="#android:color/transparent
<Spinner
android:id="#+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:clickable="false"
android:focusable="?android:attr/windowOverscan"
android:focusableInTouchMode="false"
android:pointerIcon="arrow"
android:spinnerMode="dialog"
android:theme="#style/ThemeOverlay.AppCompat.Light" />
Koltin Reflection
fun AppCompatSpinner.dismiss() {
val popup = AppCompatSpinner::class.java.getDeclaredField("mPopup")
popup.isAccessible = true
val listPopupWindow = popup.get(this) as ListPopupWindow
listPopupWindow.dismiss()
}
I am using WebView in an ActivityGroup and it will throw an exception if WebView show Dialog and complain the activity is not valid. But it's okay if I set the context of the WebView to the TOP activity. So I wish to know how to set the context in the layout xml ?
You can use layoutinflater to achieve this:
View viewToLoad = LayoutInflater.from(this.getParent()).inflate(R.layout.yourLayoutName, null);
this.theSpinner = (Spinner) viewToLoad.findViewById(R.id.Spinny);
this.setContentView(viewToLoad );
Hope that helps. for dialog you can just change context from this to
this.getParent()
So I wish to know how to set the context in the layout xml ?
That's not possible. Though, I have some experience with ActivityGroup, so I know how to solve this problem:
// in your ActivityGroup...
public class YourActivityGroup extends ActivityGroup{
public static YourActivityGroup self;
public YourActivityGroup(){
self = this;
// the rest of your code here
}
}
Then, when you need a context in order to show a dialog or a Toast or whatever, you use YourActivityGroup.self.