I am very new to android development and I am trying to learn how to add a Toolbar to a relative view programmatically. Essentially, I am trying to do the Blank project template in code instead of using the XML based approach. My application will launch but all I see is the TextView I have added and do not see Toolbar or Menu inflated and place on the toolbar at the top of the screen. Here is the code I have thus far:
public class MainActivity extends AppCompatActivity {
private RelativeLayout relativeLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create the relative layout programmatically
createRelativeLayout();
// Set the content view with the instantiated relative layout
setContentView(this.relativeLayout);
// Create and add the action bar
setSupportActionBar(createToolbar());
// Create a text view and add it
this.relativeLayout.addView(createTextView());
}
private void createRelativeLayout() {
relativeLayout = new RelativeLayout(this);
// Specifies the layout properties
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT
);
relativeLayout.setLayoutParams(relativeParams);
}
private TextView createTextView() {
TextView textView = new TextView(this);
// Set initial layout parameters
RelativeLayout.LayoutParams textViewParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
// Set alignment parameters
textViewParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
textViewParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
textViewParams.setMargins(0, 82, 0, 0);
textView.setText(R.string.app_name);
textView.setLayoutParams(textViewParams);
return textView;
}
private Toolbar createToolbar() {
Toolbar toolbar = new Toolbar(this);
Toolbar.LayoutParams toolBarParams = new Toolbar.LayoutParams(
Toolbar.LayoutParams.MATCH_PARENT,
R.attr.actionBarSize
);
toolbar.setLayoutParams(toolBarParams);
toolbar.setBackgroundColor(Color.BLUE);
toolbar.setPopupTheme(R.style.AppTheme_PopupOverlay);
toolbar.setVisibility(View.VISIBLE);
return toolbar;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Any help is greatly appreciated, thanks.
SHORT ANSWER: You should use RelativeLayout.LayoutParams when adding view to RelativeLayout
You have assigned a Toolbar.LayoutParams as layout params to your toolbar, it won't work unless you assign a RelativeLayout.LayoutParams to your toolbar.
In android view inflation, the layout param of each child view should be set according to it's parent. if your toolbar was for example in a LinearLayout you should've used 'LinearLayout.LayoutParams' as your toolbar's layout params.
Related
I am trying to overlap system bottom navigation bar using window manager but i can`t do it. I am Using bellow code.I have set gravity to bottom, therefore it show view layer in bottom of my activity view not not overlapping bottom navigation bar.
public void onCreate(Bundle savedInstancestate)
{
super.onCreate(savedInstancestate);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);7
manager = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
localLayoutParams = new WindowManager.LayoutParams();
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
localLayoutParams.gravity = Gravity.BOTTOM;
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
// this is to enable the notification to recieve touch events
//WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN |
//WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
// Draws over navigation bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
//localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
localLayoutParams.height = (int) (50 * getResources().getDisplayMetrics().scaledDensity);
localLayoutParams.format = PixelFormat.TRANSPARENT;
view = new customView(this);
manager.addView(view, localLayoutParams);
setContentView(R.layout.Imges);
}
public class customView extends ViewGroup {
public customView(Context context) {
super(context);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v("customView", "------Intercepted-------");
return true;
}
}
Using this code i can't overlap navigation,Its shows new custom view in bottom of my activity view but can not overlap navigation bar with custom view.
any one can help me on this, to overlap navigation bar with custom view.?
There are actually some solutions.You cannot overlap in the means of making it totally disappear since there are devices in market without the hardware buttons. However you can elegantly arrange your layout accordingly.
For example,
Add this to your styles.xml (v21 )in a values dir:
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
or if it does not work,
boolean hasMenuKey = ViewConfiguration.get(getContext()).hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
if(!hasMenuKey && !hasBackKey) {
// Do whatever you need to do, this device has a navigation bar
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
);
params.setMargins(0, 0, 0, 75);
entrancelayout.setLayoutParams(params);
entrancelayout.requestLayout();
}
I had a FrameLayout, you can use it for whatever layout you have. SetMargins adds margin to buttom in example. It assumes System Bar is there if there are no hardware back and menu buttons.
I am going through various links on this topic. I haven't found anything useful in my case. I want to create a Web View in Android dynamically. I will add nothing onto the xml layout file.
Now I want to do two things in particular:
1. I want to set the size of this Web View to a custom width and height and set it at the bottom of the Layout.
2. Once the page loads in the Web view. On click on the Web view should resize and go full screen(which means fill_parent on width and height for web view in its parent layout).
My current code looks something like this below which does not work particularly well as the full screen does not fit the content to screen:
public class MainActivity extends Activity {
RelativeLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layout=(RelativeLayout)findViewById(R.id.test);
final WebView web = new WebView(this);
//web.setId(1);
web.getSettings().setJavaScriptEnabled(true);
web.loadData("<script type=\"text/javascript\" src=\"http://www..myurl.com/myfolder/banner.php\"></script>", null, null);
layout.addView(web, new LayoutParams(300,100));
web.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
web.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
return false;
}
});
}
#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;
}
}
If I understand your problem correctly, you may want to consider the following approach.
First, declare and initialize the (parent) relative layout, together with its parameters and set it as the content view (delete setContentView(R.layout.activity_main);).
final RelativeLayout layout = new RelativeLayout(this);
final RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
getWindowManager().getDefaultDisplay().getWidth(),
getWindowManager().getDefaultDisplay().getHeight());
layout.setLayoutParams(params);
setContentView(layout);
Then, initialize the web view and its parameters, and add the "bottom rule" to the parameters.
final WebView web = new WebView(this);
web.getSettings().setJavaScriptEnabled(true);
web.loadData(
"<script type=\"text/javascript\" src=\"http://www..myurl.com/myfolder/banner.php\"></script>",
null, null);
RelativeLayout.LayoutParams webViewParams = new RelativeLayout.LayoutParams(
300, 100);
webViewParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
Finally, add the web view to your (parent) relative layout and add its listener.
layout.addView(web, webViewParams);
web.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View arg0, MotionEvent arg1) {
web.setLayoutParams(params);
return false;
}
});
Hope this is what you needed.
Cheers!
How do I show a progress dialog on Android without blocking clicks on the other UI elements on the screen (like Ads) ?
public void addProgressBar(Activity activity){
final ViewGroup rootFrameLayout = (ViewGroup) activity.getWindow().peekDecorView();
final ViewGroup modal = new RelativeLayout(activity);
ProgressBar progressBar = new ProgressBar(activity);
LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
modal.addView(progressBar, layoutParams);
rootFrameLayout.addView(modal, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
rootFrameLayout.invalidate();
}
You have to use ProgressBar view, and create a separate overlay for the progress bar.
The most transparent way would be to create an abstract Activity and override the setContentView() method (both with id, and View, shown only with id). Than you can inherit your Activities from this one, and use it as a normal Activity with the added benefit of showProgress and hideProgress methods.
private HashMap<View, ProgressBar> progressBars = new HashMap<View, ProgressBar>();
private RelativeLayout overlay;
public void setContentView(int id) {
FrameLayout combinedView = new FrameLayout();
combinedView.setLayoutParams(new ViewGroup.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
View background = getLayoutInflater().inflate(id, null);
background.setLayoutParams(new ViewGroup.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
combinedView.addView(background);
overlay = new RelativeLayout();
overlay.setLayoutParams(new ViewGroup.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
combinedView.addView(overlay);
super.setContentView(combinedView);
}
public void showProgress(View view) {
ProgressBar progressBar = progressBars.get(view);
if (progressBar == null) {
progressBar = new ProgressBar();
progressBars.put(view, progressBar);
progressBar.setLayoutParams(new ViewGroup.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
overlay.addView(progressBar);
}
int[] position = view.getLocationOnScreen();
int width = view.getWidth();
int height = view.getHeight();
int progressWidth = progressBar.getWidth();
int progressHeight =progressBar.getHeight();
progressBar.setMargins(position[0] + width / 2 - progressWidth/2,
position[1] + height / 2 - progressHeight/2,0,0);
progressBar.setVisibility(View.VISIBLE);
}
public void hideProgress(View view) {
ProgressBar progressBar = progressBars.get(view);
if (progressBar != null) {
progressBar.setVisibility(View.INVISIBLE);
}
}
You can create a completely transparent Linear or any other kind of layout with a ProgressBar in center and add this layout in a FrameLayout which contain all your other controls. Now when you want to show the progress bar make this layout visible and make invisible when you do not want it to show.
bankings method I felt was the best and the simplest to implement. Just for the convenience of anybody wanting to use it, rather make the method return ProgressBar and when you want to remove this progress bar, you can use this return value to just set its visibility to gone as shown for example
progressBar.setVisibility(View.GONE);
Hope it adds value to the above answers.
When a dialog appears, it adds a layer to underlaying view blocking all events on it.
To achieve what you are looking for, you can create a view similar to dialog view and show it instead of dialog. For dialogs and transparent background activity, your target won't be achieved.
#banking's method is sweet and short, I have modified it a little to use with layout file instead of creating it with Java code:
progress_spinner.xml: (in layout folder)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
<ProgressBar
android:id="#+id/ProgressBar"
style="?android:attr/progressBarStyleInverse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
</RelativeLayout>
Java:
ProgressBar progressBar=null;
public void addProgressBar(Activity activity) {
ViewGroup rootFrameLayout = (ViewGroup) activity.getWindow().peekDecorView();
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View progressModal = inflater.inflate(R.layout.progress_spinner, rootFrameLayout, false);
rootFrameLayout.addView(progressModal, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
rootFrameLayout.invalidate();
progressBar = (ProgressBar) progressModal.findViewById(R.id.ProgressBar);
}
public void hideProgressBar() {
if (progressBar != null)
progressBar.setVisibility(View.INVISIBLE);
}
public void showProgressBar() {
if (progressBar != null)
progressBar.setVisibility(View.VISIBLE);
}
How can we add buttons at dynamic positions in layout or using canvas, not in table layout?
Can anyone please help me on this?
Use RelativeLayout to position your controls where you like them. Have a look at this link:
Dynamic TextView in Relative layout
and here
How to create a RelativeLayout programmatically with two buttons one on top of the other?
If you like to achieve it within XML only. Look here:
http://www.mkyong.com/android/android-relativelayout-example/
Here an example how you could use the RelativeLayout to position your controls dynamically:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Creating a new RelativeLayout
RelativeLayout mainRelativeLayout = new RelativeLayout(this);
// Defining the RelativeLayout layout parameters with Fill_Parent
RelativeLayout.LayoutParams relativeLayoutParameters = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
// Creating a new Left Button
Button buttonLeft = new Button(this);
buttonLeft.setText("Left");
// Creating a new Left Button with Margin
Button buttonLeftWithMargin = new Button(this);
buttonLeftWithMargin.setText("Left with Margin");
// Creating a new Center Button
Button buttonCenterParent = new Button(this);
buttonCenterParent.setText("Center");
// Creating a new Bottom Button
Button buttonBottom = new Button(this);
buttonBottom.setText("Bottom");
// Add a Layout to the Buttons
AddButtonLayout(buttonLeft, RelativeLayout.ALIGN_PARENT_LEFT);
AddButtonLayout(buttonCenterParent, RelativeLayout.CENTER_IN_PARENT);
AddButtonLayout(buttonBottom, RelativeLayout.ALIGN_PARENT_BOTTOM);
// Add a Layout to the Button with Margin
AddButtonLayout(buttonLeftWithMargin, RelativeLayout.ALIGN_PARENT_LEFT, 30, 80, 0, 0);
// Add the Buttons to the View
mainRelativeLayout.addView(buttonLeft);
mainRelativeLayout.addView(buttonCenterParent);
mainRelativeLayout.addView(buttonBottom);
mainRelativeLayout.addView(buttonLeftWithMargin);
// Setting the RelativeLayout as our content view
setContentView(mainRelativeLayout, relativeLayoutParameters);
}
private void AddButtonLayout(Button button, int centerInParent, int marginLeft, int marginTop, int marginRight, int marginBottom) {
// Defining the layout parameters of the Button
RelativeLayout.LayoutParams buttonLayoutParameters = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
// Add Margin to the LayoutParameters
buttonLayoutParameters.setMargins(marginLeft, marginTop, marginRight, marginBottom);
// Add Rule to Layout
buttonLayoutParameters.addRule(centerInParent);
// Setting the parameters on the Button
button.setLayoutParams(buttonLayoutParameters);
}
private void AddButtonLayout(Button button, int centerInParent) {
// Just call the other AddButtonLayout Method with Margin 0
AddButtonLayout(button, centerInParent, 0 ,0 ,0 ,0);
}
}
And you should get something like this:
I have a question regarding Android Activitys:
An Activity has the Method addContentView(View) while a ViewGroup has a (similar?) addView(View) Method.
Unfortunately its undocumented where the View from addContentView is placed. Is it like a LinearLayout just adding the View to the bottom, or is it more like a FrameLayout, which adds its Views "onTop" ? Does it depend on the ViewGroup set by setContentView?
If I dive into the sources I see that addContentView will call Window's abstract Method addContentView. Unfortunately I cannot see which class is implementing this Method. So whats the behaviour of Activitys addContentView exactly?
The base layout of every activity is a FrameLayout. This means the layout you usually set via setContentView() is a child of this layout. addContentView() adds just another child, therefore it behaves like a FrameLayout (which means it adds new UI elements above existing ones).
You can check this by using a tool called hierachyviewer from your ANDROID_SDK\tools folder. Here are two screenshots:
This is the layout before calling addContentView(), my activity consists of the default FrameLayout, holding a LinearLayout with a Button (my layout here). This is reflected in the bottom row here, the other elements above are the title/statusbar.
After adding a TextView via addContentView() it looks like this. You can see that the base FrameLayout got a new child.
public void addContentView(View view,
LayoutParams params) {
mActivity.addContentView(view, params);
}
//
public static void SetActivityRoot(Activity c) {
View v = ((ViewGroup)c.findViewById(android.R.id.content)).getChildAt(0);
ScrollView sv = new ScrollView(c);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
sv.setLayoutParams(lp);
((ViewGroup) v.getParent()).removeAllViews();
sv.addView((View) v);
c.addContentView(sv, lp);
}
//
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout mainLayout =
(LinearLayout)findViewById(R.id.mainlayout);
//newButton added to the existing layout
Button newButton = new Button(this);
newButton.setText("Hello");
mainLayout.addView(newButton);
//anotherLayout and anotherButton added
//using addContentView()
LinearLayout anotherLayout = new LinearLayout(this);
LinearLayout.LayoutParams linearLayoutParams =
new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
Button anotherButton = new Button(this);
anotherButton.setText("I'm another button");
anotherLayout.addView(anotherButton);
addContentView(anotherLayout, linearLayoutParams);
}
}