In my activity there are 3 buttons. By clicking on the first button, I want a dialog to appear with a graph (in the layout itself it works fine).
btn1 = (Button)findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog = new Dialog(ChartsDuration.this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_charts1);
// code to show a graph. Here I have a function that calls drawChartAll(),
// but since the layout is declared outside the dialog it cannot render it to the
// linearlayout, and my graph1 linearlayout will be empty.
dialog.show();
}
});
Tha graph uses data that are queried in functions outside like
public void drawChartAll()
{
//blablabla and this is how I define the layout and render the graph to it:
LinearLayout layout = (LinearLayout) findViewById(R.id.graph1);
mChartView = ChartFactory.getBarChartView(ChartsDuration.this, buildBarDataset(titles, values),renderer,Type.DEFAULT);
mChartView.setBackgroundColor(renderer.getBackgroundColor());
layout.addView(mChartView);
}
So without the dialog, I can easily show the graph in the graph1 LinearLayout e.g below the buttons, because they are "on the same levels", but I want to show the graph in a dialog opened by clicking on a button. Because if I were in a dialog I would do this: LinearLayout layout = (LinearLayout)dialog.findViewById(R.id.graph1); But now I cannot do this, since I am outside the dialog.
How do I reach this layout?
Edit:
user113215 I did this:
in the activity:
LayoutInflater inflater = LayoutInflater.from(ChartsDuration.this);
customDialog = (ViewGroup) inflater.inflate(R.layout.dialog_charts1, null);
btn1 = (Button)findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.setContentView(customDialog);
//queries
dialog.show();
}
});
and in drawChartAll:
public void drawChartAll()
{
//code
LinearLayout layout = (LinearLayout) customDialog.findViewById(R.id.graph1);
}
Is this what you mean? This throws me a nullpointer exception to dialog.setContentView(customDialog); line.
If I understand the problem correctly, you're having trouble manipulating things on the layout that's going into the dialog. Instead of calling setContentView(int), inflate the layout yourself and then use setContentView(View).
LayoutInflater inflater = LayoutInflater.from(this);
ViewGroup customDialog = (ViewGroup) inflater.inflate(R.layout.dialog_charts1, null);
// Do chart things here
// Prefix all calls to findViewById with "customDialog."
LinearLayout layout = (LinearLayout) customDialog.findViewById(R.id.graph1);
mChartView = ChartFactory.getBarChartView(ChartsDuration.this, buildBarDataset(titles, values),renderer,Type.DEFAULT);
mChartView.setBackgroundColor(renderer.getBackgroundColor());
layout.addView(mChartView);
// Put the manipulated layout into the dialog
dialog.setContentView(customDialog);
You can use this same trick to take advantage of the AlertDialog.Builder class while still filling the dialog with a custom layout.
Make the dialogvariable a field in your Activity class. You can reach it from anywhere. You can still use dialog.findviewbyid throughout you Activity. Just make sure setcontentView has been called before you call findviewbyid
Edit: I hope when you wrote since I am outside the dialog. you meant you could not access the variable
Related
Here is what I am aiming for:
I am unsure if I am doing this correctly. There are probably better,more efficient, and cleaner ways to do it, but I need to know how.
This layout was designed in xml and inflated via an inflater. The produced view was then placed into an AlertDialog. Thus, this is seen as an AlertDialog by the user.
My concern is with the tags section at the bottom. I want this to work like how Tumblr tags work. Type a string, hit the button, and a button with that tag name will show up in the blank section below it.
Now, if you click on those buttons (with their respective tag names), they will disappear from the frame.
I have several concerns.
I have trouble implementing listeners. If the AddTag button creates more buttons in the (currently invisible, but present) LinearLayout, then what about the created buttons? How do those buttons implement onClick listeners that will remove themselves from the LinearLayout if they were created in some inner method defined from the AddTag button's onClick method?
I am afraid about having to declare some of these views as FINAL in order to reference them in button methods and inner classes. I am now stuck because of this.
Do I have to define my own layout for the tag buttons? You see, a LinearLayout displays things one after the other, yes? I want to try to recreate how some social networking sites do it. Fill the layout with buttons from top to bottom, left to right. If there is no room left in the current row, go to the next one and add the tag button there. It's basically a dynamic LinearLayout that has autowrapping.
If there are any better ways of implementing this, please let me know a general step by step of what to do. I have not learned Fragments yet, but I think it may be VERY applicable here. Also, should I be creating a class that extends ViewGroup, inflating the XML there, and adding helper methods to handle things? I suppose from a DialogFragment I could then addView(the class I just created) and work from there?
Here is my current code by the way. I am stuck and stumped.
/**
* Opens a view for the user to define their new action and add it to the
* dictionary.
*
* #param view
*/
public void defineNewAction(View view) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
View viewToSet = inflater.inflate(
R.layout.define_new_action_window_layout,
null);
final EditText newActionName = (EditText) viewToSet
.findViewById(R.id.set_action_name);
final RadioGroup priorityGroup = (RadioGroup) viewToSet
.findViewById(R.id.radiogroup_set_priority);
final EditText goalTimeHours = (EditText) viewToSet
.findViewById(R.id.set_goal_time_hours);
final EditText goalTimeMinutes = (EditText) viewToSet
.findViewById(R.id.set_goal_time_minutes);
final EditText addTagsInput = (EditText) viewToSet
.findViewById(R.id.add_tags_input);
Button addTagButton = (Button) viewToSet.findViewById(R.id.btn_add_tags);
final ArrayList<String> tags = new ArrayList<String>();
final LinearLayout currentTagsLayout = (LinearLayout) viewToSet
.findViewById(R.id.current_tags);
addTagButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String tag = addTagsInput.getText().toString();
tags.add(tag);
Button newTag = new Button(builder.getContext());
int tagId = tag.hashCode();
if (tagId < 0)
tagId *= -1;
newTag.setId(tagId);
newTag.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Button toRemove = (Button) currentTagsLayout.findViewById(tagId);
currentTagsLayout.removeView(toRemove);
}
});
currentTagsLayout.addView(newTag);
}
});
builder.setTitle("Define your action.");
builder.setView(viewToSet);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
String name = newActionName.getText().toString();
int priority = priorityGroup.getCheckedRadioButtonId();
int goalHours = Integer
.parseInt(goalTimeHours.getText().toString());
int goalMinutes = Integer.parseInt(goalTimeMinutes.getText()
.toString());
}
});
builder.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
I have trouble implementing listeners
There's no trouble. For the functionality you are trying to achieve, you can keep adding buttons and setting OnClickListeners on them. You don't even need to give them an id, or track them in any way. The following code inside your OnClickListener will do:
newTag.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Use the View given to you
currentTagsLayout.removeView(v);
}
});
I am afraid about having to declare some of these views as FINAL
This is how Java works. I haven't noticed any crippling effects of this. You can also declare your variables as global to not have to define them as final. But I don't see why declaring them as final is an issue. Could you provide an example where this is a problem?
Do I have to define my own layout for the tag buttons?
This is something you will have to deal with yourself. It's a design decision. If you need auto-wrapping support, you can look at Android Flow Layout: Link. It's an extended LinearLayout that supports auto-wrap of its contents.
I have not learned Fragments yet, but I think it may be VERY
applicable here
I don't see why they would be.
Note/Aside: Some kind of a check here would be better:
String tag = "";
if (!addTagsInput.getText().toString().equals("")) {
tag = addTagsInput.getText().toString();
} else {
// handle empty string
}
I am trying to bring a new layout by pressing a button in my android app. Here is the code piece:
Button button = (Button)findViewById(R.id.btnAccept);
button.setOnClickListener(new View.OnClickListener() {
LayoutInflater layoutInflater = LayoutInflater.from(getBaseContext());
View promptView = layoutInflater.inflate(R.layout.empty_layout, null);
public void onClick(View v) {
// What should I write here to prompt empty_layout?
}
}
I dont know how to use "promptView". Can you give me some insight please?
Thank you guys!
If its the whole view of your screen then use
setContentView(prompView);
If its only a portion of a view then use
yourPortionViewContainer.addView(prompView);
Or may be you could use Fragment.
you should create Intent to open new Activity or create Fragment and let FragmentManager show it.
I don't know if i understand your question correctly but what I would do to add a layout when a button is pressed is to do it programmatically like this:
LinearLayout mainLayout;
mainLayout = (LinearLayout)findViewById(R.id.mainLayout)//assuming u gave the main layout an id of mainLayout in your XML file
public void onClick(View v) {
LinearLayout layout = new LinearLayout(this);
LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);//create variable to store layout parameters
layout.setOrientation(LinearLayout.VERTICAL);//set orientation of layout
layout.setLayoutParams(params);//set layout parameters
mainLayout.addView(layout);//add the newly created layout to the already existing layout
}
I have created an activity with two buttons at the top. One button to show "SMS Logs" and second to show "Call Logs".
On clicking "SMS Logs" button, i am dynamically creating textviews and linear layout to show sms logs.
On Clicking "Call Logs", i am dynamically creating another textviews and linear layout to show call logs.
But the problem is that, once if we click "sms log" button and then we click "call log" button, the previously created linear layouts are not removed and the both(previous layouts and the current layouts) are shown simultaneously.
But i want that the previous layouts should be removed on clicking the second button.
Which function, should i use to remove the previous viewgroups or the layouts. Tell me if you need to read my class file.
Edit:
This is my Activity's code,
public class General extends Activity
{
String phone, message;
TextView Logs;
View layout, callLayout;
TextView data, callData, line, callLine;
Button smsLog, callLog;
LinearLayout ll, callll;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.general_main);
Logs = (TextView)findViewById(R.id.Logs);
layout = findViewById(R.id.layout);
callLayout = findViewById(R.id.layout);
smsLog = (Button)findViewById(R.id.smsLogs);
callLog = (Button)findViewById(R.id.callLogs);
smsLog.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
callLayout.setVisibility(View.GONE);
ll = new LinearLayout(getApplicationContext());
ll.setOrientation(LinearLayout.VERTICAL);
data = new TextView(getApplicationContext());
data.setText("First Line");
data.setTextColor(Color.YELLOW);
line = new TextView(getApplicationContext());
line.setText("Second Line");
((ViewGroup) ll).addView(data);
((ViewGroup) layout).addView(line);
((ViewGroup) layout).addView(ll);
}
});
callLog.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
layout.setVisibility(View.GONE);
callll = new LinearLayout(getApplicationContext());
callll.setOrientation(LinearLayout.VERTICAL);
callData = new TextView(getApplicationContext());
callLine = new TextView(getApplicationContext());
callData.setText("Third Line");
callLine.setText("Fourth Line");
((ViewGroup) callll).addView(callData);
((ViewGroup) callLayout).addView(callLine);
((ViewGroup) callLayout).addView(callll);
}
});
}
}
I have removed the extra code and made it simple to understand.
You can use FrameLayout to solve your problem. But I recommend you to use tabview.Here is the link that demonstrates how to develop tabbed applications.Good Luck
You could implement a TabView.
But having your current setup just change the visibility of one view group to GONE and the other to VISIBLE.
GONE will make the view invisible and it won't take up any space anymore.
EDIT based on the code added to the question
Both your layout and callLayout are using the same XML view. Implement 2 identical views in your xml and keep one visible and one gone. This way when you set layout or callLayout visibility to GONE they are 2 different ones not the same. So your onClick() will have something like this:
for smsLog:
layout.setVisibility(View.GONE);
callLayout.setVisibility(View.VISIBLE);
for callLog:
callLayout.setVisibility(View.GONE);
callLayout.setVisibility(View.VISIBLE);
I have a curious problem with getting reference on TextView, SeekBar and other widgets. My AlertDialog looks like this:
public class LineDialog extends AlertDialog {
private static SeekBar seekBar1, seekBar2, seekBar3;
private static TextView textView1, textview2, textView3;
protected LineDialog(final Context context, final DrawView drawView) {
super(context);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View dialogLayout = inflater.inflate(R.layout.line_dialog, null);
setView(dialogLayout);
setTitle("Line properties");
textView1 = (TextView) findViewById(R.id.textView1); // TODO Code crash here :(
setButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
seekBar1 = (SeekBar) findViewById(R.id.seek1);
// some other code...
}
});
}
When I want get reference in Line where is
textView1 = (TextView) findViewById(R.id.textView1);
Logcat send me an Error
requestFeature() must be called before adding content
But when I get reference in onClick() method in LineDiealog(AlertDialog) everything works fine. Unfortunately this is too late, because I need this reference before LineDialog.show() is called...
You almost had it there in your original code. You saved the View returned by LayoutInflater, so that's the one you should use when calling findViewById() so it must be dialogLayout.findViewById(...). I was having the same issue myself and works like charm now.
Here is an example of the custom AlertDialogbox and How to implement a custom AlertDialog View
you can see how to add the view to the alertdialogbox.
You must either reference your textView by LinearLayout or by android:id in the xml file.
LinearLayout example:
LinearLayout mainLinear = new LinearLayout(this);
mainLinear.addView(textBox);
the add text to the box:
textBox.addText("This is the text to add to the text box");
xml reference (you must create the text box in xml first!!!!):
TextView text1=(TextView) findViewById(R.id.NAME);
text1.setText("Hello please pick an option below");
The NAME portion must be replaced with the android:id name in the .xml file
i set my activity theme to translucent so as to see through to the underneath activity window.
I want to know if it's possible to enable click event when user tap on empty area on this translucent activity?
Thanks,
dara kok
It is possible to add click event to your activity. You need to do as below:
You could have done setContentView(R.layout.main); in onCreate() of your activity.
In main.xml, give some id to the root layout. For eg.,
Lets consider you have root as LinearLayout with id set as below,
Then in onCreate() of your activity, you will have to do the following:
LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);
layout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
Overriding this would work:
http://developer.android.com/reference/android/app/Activity.html#onTouchEvent(android.view.MotionEvent)
However i think it's your translucent activity that will get the taps, not the one visible under it.
You can add OnClickListener on parent view of your layout.
For example, add android:id="#+id/some_id" to your parent LinearLayout in main.xml.
Then add this code after setContentView in onCreate method:
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.some_id);
FrameLayout frameLayout = (FrameLayout) linearLayout.getParent(); // Get parent FrameLayout
frameLayout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed(); // Close activity, for example
}
});
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// empty block for prevent frameLayout click event, if you need
}
});