onCreateDialog and dynamic dialogs (Android) - java

I have a little problem. In my program I defined
protected Dialog onCreateDialog(int id) {
if (id == CONTEXT_MENU_ID) {
return createMyDialog();
}
return super.onCreateDialog(id);
}
and then show the dialog calling
showDialog(CONTEXT_MENU_ID)
My problem is that sometimes I want to change the texts of the Dialog dynamically between executions. But with that method the Dialog is never recreated. How can I make the createMyDialog() to be called before showing the Dialog?
Thanks

If you want to change dialog settings (text, etc.) you need to do it in onPrepareDialogMethod it will be called each time you call showDialog method

This might be worth a try. I haven't tested it out. To the dialog if you set the textview as its content, then you can set an id to it.
TextView text = new TextView(this);
ViewGroup.LayoutParams vp = new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
text.setLayoutParams(vp);
text.setText("HI");
text.setId(1005);
dialog.setContentView(text);
So the next time when you try to update the textview, you might be able to access it using the id.
((TextView)dialog.getWindow().getDecorView().findViewById(1005))
.setText("New Text");

Related

How to know which Toggle Buttons are clicked from dynamically added view?

This is my first time with android programming and I got stuck.
Now I'm trying to add view dynamically which contains toggle buttons, and edittext. However, whenever I select toggle button, options I created only works on last created view.
Options are simple. There are two toggle buttons and they can be clicked mutually exclusive
example
which means whenever I add new views such as B and C in above, the options are only worked on C while not in B. How can I make it to work on every view?
public void onAddField(View v){
LayoutInflater inflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView=inflater.inflate(R.layout.data_gledger_add_new,null);
tbg_add=(ToggleButton)rowView.findViewById(R.id.add_toggle_gledger);
tbc_add=(ToggleButton)rowView.findViewById(R.id.add_toggle_credit);
if(create_box<4){
csl.addView(rowView,csl.getChildCount()-1);
Log.d("create_box",String.valueOf(create_box));
create_box++;
}
else{
Log.d("create_box","full");
create_box=4;
}
tbg_add.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
if(tbg_add.isChecked()){
get_add_cla="menu1";
tbg_add.setTextColor(getResources().getColor(R.color.color_white));
tbc_add.setChecked(false);
tbc_add.setTextColor(getResources().getColor(R.color.color_black));
}
else{
get_add_cla="";
tbg_add.setTextColor(getResources().getColor(R.color.color_black));
}
}
});
//대변 선택
tbc_add.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
if(tbc_add.isChecked()){
get_add_cla="menu2";
tbc_add.setTextColor(getResources().getColor(R.color.color_white));
tbg_add.setChecked(false);
tbg_add.setTextColor(getResources().getColor(R.color.color_black));
}
else{
get_add_cla="";
tbc_add.setTextColor(getResources().getColor(R.color.color_black));
}
}
});
}
I forgot to mention that views are added by clicking button.
android:onClick="onAddField"
The problem almost certainly stems from the fact that you are re-using instance fields (tbg_add and tbc_add) as add new views dynamically.
tbg_add=(ToggleButton)rowView.findViewById(R.id.add_toggle_gledger);
tbc_add=(ToggleButton)rowView.findViewById(R.id.add_toggle_credit);
Because you are re-assigning these fields and also referencing them from the click listeners, you'll always be referencing the most recently created toggle buttons.
Change these to be local variables and everything should work fine.
ToggleButton ledger=(ToggleButton)rowView.findViewById(R.id.add_toggle_gledger);
ToggleButton credit=(ToggleButton)rowView.findViewById(R.id.add_toggle_credit);
Unrelated to your problem, but also something you should fix, is the fact that you're passing null as the second parameter to your inflate() call:
final View rowView=inflater.inflate(R.layout.data_gledger_add_new,null);
When you pass null in this manner, the system won't have any ability to correctly handle the LayoutParams (anything starting with android:layout_ in the xml file) for the newly-inflated view.
You know that you're going to wind up adding the rowView to your csl view, so you should pass that as the second parameter. Once you do that, you also have to pass false as a third parameter to make sure that the inflate() call actually returns the rowView and not its new parent (csl).
final View rowView=inflater.inflate(R.layout.data_gledger_add_new, csl, false);

Alert Dialogue null object reference

I have an alertDialogue popup when a user wants to create a game, and it asks the user how many points they would like to gamble in the game, but it keeps throwing a null reference error and I am not too sure why.
This is my alertDialogue positive button click listener
alertDialog.setPositiveButton("Confirm Wager", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
createLobbyGame();
double wagerD;
String wager;
TextView wagerRV = findViewById(R.id.wagerRV);
wagerD = Double.parseDouble(edittext.getText().toString());
wager = Double.toString(wagerD);
boolean wage = wager.endsWith("0");
if(wage) {
wagerRV.setText(wager+"0");
} else {
wagerRV.setText(wager);
}
}
});
It throws an error when it tries to setText. This is the error it throws
Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
I know I had this working in the past, but I must have changed something to make it not work properly anymore but I have no idea what I would have changed.
I know this is a very common and simple problem, but I have looked at many other answers and have not found a solution that works for me.
Any help?
TextView declaration:
TextView wagerRV = (TextView) ((AlertDialog.Builder) alertDialog).findViewById(R.id.wagerRV);
How I am defining alertDialog:
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(FlipCoinLobby.this);
final EditText edittext = new EditText(FlipCoinLobby.this);
alertDialog.setView(edittext);
Your wagerRV is null because it can't find R.id.wagerRV.
You need to retrieve views from within onClick() using the dialog reference.
Change
TextView wagerRV = findViewById(R.id.wagerRV);
to
TextView wagerRV = (TextView) ((AlertDialog) alertDialog).findViewById(R.id.wagerRV);
Remove any unnecessary casting (I don't have IDE at the moment).
Update based on comments and question edit:-
alertDialog.setView(edittext) --> your alertDialog does not have any TextView with id R.id.wagerRV. Please check out some examples online on setting the content view with XML and that XML should have that TextView. If your wagerRV is in the activity and not inside the dialog, then declare it at the activity level, not inside onClick of alertDialog.
Update 2
You need to change your builder to the actual AlertDialog using AlertDialog alertDialog = alertDialogBuilder.create();. And then the casting will work too.

Cant set text to EditText in DialogFragment

I have a button in listview row that when I click on it I want a dialogFragment to be open and set the text of an edit text (that located inside the dialogFragment) to some String.
The problem is: the app shut down when it comes to the line of the settext method.
This is the code I use to open the dialogFragment and set text to it.
public void onClick(View v) {
FragmentManager manager = getFragmentManager();
View parentRow = (View) v.getParent();
ListView listView = (ListView) parentRow.getParent();
final int position = listView.getPositionForView(parentRow);
TrempData data = adapter.getItem(position); //from here im getting the data that i want to set to the edit text.
Addtremp trempDialog = new Addtremp();
trempDialog.show(manager, "Addtremp");
trempDialog.from.setText(data.get_from());
trempDialog.to.setText(data.get_to());
trempDialog.date.setText(data.get_date());
trempDialog.time.setText(data.get_time());
trempDialog.extra.setText(data.get_extras());
}
Hope someone could help me.
Thanks.
Your App will surely crash due to NullPointerException. Because you are trying to set data on UI which is not rendered yet.
What steps should follow?
Pass data to DialogFragment which is going to display on UI in a form of arguments.
Create callback which will inform you when UI is rendered on Dialog. Check this Callback to a Fragment from a DialogFragment
. On getting listener you could set data on your UI components.
Personally I prefer solution1 and for that you should read passing argument to DialogFragment

how to make entire view in dialog clickable?

i have dialog and text inside eache view that i can click on .
i want all the view to be clickable insted only the text .
the code :
final Dialog dialog = new Dialog(List_Lists.this);
dialog.setContentView(R.layout.dialog_edit_tables);
dialog.setTitle("Action for " + table);
TextView delete = (TextView) dialog
.findViewById(R.id.tvDeleteTable);
TextView cancel = (TextView) dialog.findViewById(R.id.tvCancel);
OnClickListener l = new OnClickListener() {
#Override
public void onClick(View v) {
dbAdapter = new DBmethods(getApplicationContext());
switch (v.getId()) {
case R.id.tvDeleteTable:
viewListsAdapter.listsV.remove(pos);
dbAdapter.deleteTable(table);
break;
case R.id.tvCancel:
dialog.dismiss();
break;
case R.id.bTableRenameName:
if(dbAdapter.checkTableNameOK(List_Lists.this ,newName.getText().toString())){
viewListsAdapter.listsV.remove(pos);
viewListsAdapter.listsV.add(pos, newName.getText().toString().trim());
dbAdapter.renameTable(table , newName.getText().toString().trim());
renamedialog.dismiss();
};
break;
default:
break;
}
// if button is clicked, close the custom dialog
dialog.dismiss();
lv.invalidateViews();
}
};
delete.setOnClickListener(l);
cancel.setOnClickListener(l);
dialog.show();
}
});
}
as i said this code work fine if user press on text inside the view , but the empty view obviously wont respond . thanks !
if user press on red spot it activate the enter , if green than duplicate and so on...the current status is u have to press on the word , if u press on the colored spots it will do nothing
If im not wrong you need this to make layout clickable
try something like this
You can add a OnClickListener on it :
//onCreate
LinearLayout layout = (LinearLayout) findViewById(R.id.LinearLayout01);
layout.setOnClickListener(yourOnClickListener);
Should be working ;)
create an id of your dialog_edit_tables
let say android:id=#+id\testing in your xml.
now write this
LinearLayout yourlayout = (LinearLayout) findViewById(R.id.testing);
yourlayout.setOnClickListener(l);
hope this will help.
You haven't shown the XML layout but setting the width of the clickable text view to fill_parent should work, also make sure your parent layout also has the width set to fill_parent.
The onClickListener is not based on the text it is based on the actual component, therefore it looks as if the layout_width attribute is set to wrap_content, so the component is only then length of the text, therefore only where the text is, is clickable. Hope this makes sense.
If I am not wrong than you are using listview or tableview to display the text.
You can do one thing. Make the textview layout_width as fill_parent That way you will able to get the touch on the place that you marked.
Hope this will help.

Updating Android Tab Icons

I have an activity that has a TabHost containing a set of TabSpecs each with a listview containing the items to be displayed by the tab. When each TabSpec is created, I set an icon to be displayed in the tab header.
The TabSpecs are created in this way within a setupTabs() method which loops to create the appropriate number of tabs:
TabSpec ts = mTabs.newTabSpec("tab");
ts.setIndicator("TabTitle", iconResource);
ts.setContent(new TabHost.TabContentFactory(
{
public View createTabContent(String tag)
{
...
}
});
mTabs.addTab(ts);
There are a couple of instances where I want to be able to change the icon which is displayed in each tab during the execution of my program. Currently, I am deleting all the tabs, and calling the above code again to re-create them.
mTabs.getTabWidget().removeAllViews();
mTabs.clearAllTabs(true);
setupTabs();
Is there a way to replace the icon that is being displayed without deleting and re-creating all of the tabs?
The short answer is, you're not missing anything. The Android SDK doesn't provide a direct method to change the indicator of a TabHost after it's been created. The TabSpec is only used to build the tab, so changing the TabSpec after the fact will have no effect.
I think there's a workaround, though. Call mTabs.getTabWidget() to get a TabWidget object. This is just a subclass of ViewGroup, so you can call getChildCount() and getChildAt() to access individual tabs within the TabWidget. Each of these tabs is also a View, and in the case of a tab with a graphical indicator and a text label, it's almost certainly some other ViewGroup (maybe a LinearLayout, but it doesn't matter) that contains an ImageView and a TextView. So with a little fiddling with the debugger or Log.i, you should be able to figure out a recipe to get the ImageView and change it directly.
The downside is that if you're not careful, the exact layout of the controls within a tab could change and your app could break. Your initial solution is perhaps more robust, but then again it might lead to other unwanted side effects like flicker or focus problems.
Just to confirm dominics answer, here's his solution in code (that actually works):
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
public void onTabChanged(String tabId) {
if (TAB_MAP.equals(tabId)) {
ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_black));
iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_white));
} else if (TAB_LIST.equals(tabId)) {
ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_white));
iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_black));
}
}
});
Of course it's not polished at all and using those direct indices in getChildAt() is not nice at all...
See my post with code example regarding Customized Android Tabs.
Thanks
Spct
This is what I did and it works for me. I created this function in the activity that extends from TabBarActivity
public void updateTab(int stringID) {
ViewGroup identifyView = (ViewGroup)getTabWidget().getChildAt(0);
TextView v = (TextView)identifyView.getChildAt(identifyView.getChildCount() - 1);
v.setText(stringID);
}
You can modify this function to change the image instead of text or you can change both, also you can modify this to get any tab child. I was particularly interested in modifying the text of the first tab at runtime.
I called this function from the relevant activity using this call
getParent().updateTab(R.string.tab_bar_analyze);
Try This:
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
public void onTabChanged(String tabId) {
if (TAB_MAP.equals(tabId)) {
ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_black));
iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_white));
} else if (TAB_LIST.equals(tabId)) {
ImageView iv = (ImageView) tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_white));
iv = (ImageView) tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon);
iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_list_black));
}
}
});

Categories

Resources