I'm new in Android.
I need to draw custom view (or close if it exists) on search button click.
Now I implemented it this way:
public class CategoryActivity extends AppCompatActivity {
private FrameLayout relativeLayout;
private Toolbar myToolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
relativeLayout = (FrameLayout) findViewById(R.id.activity_demo);
myToolbar = (Toolbar) findViewById(R.id.demo_toolbar);
myToolbar.setTitle(R.string.main_page);
setSupportActionBar(myToolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.demo_activity_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
...
MyView myView = new MyView(this); //create vustom view
int cX = relativeLayout.getWidth() / 2; //calculate coordinates
int cY = relativeLayout.getHeight() / 2;
FrameLayout frameLayout = new FrameLayout(this); //create new layout
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(cX, cY);
layoutParams.setMargins(relativeLayout.getWidth() - timerX, relativeLayout.getPaddingTop() + myToolbar.getHeight(), 0, 0);
frameLayout.setLayoutParams(layoutParams);
frameLayout.addView(myView);
relativeLayout.addView(frameLayout);
return super.onOptionsItemSelected(item);
...
}
}
It should look like this
What is right way to do it?
Thanks.
I did not understand your problem completely because you have not given error log or shown problem you are getting.
I have made a simplest example to show How to add view dynamically. Check this example, after that you can ask question for your scenario.
layout : activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linear_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/btn_add_view"
android:text="Add new view dynamically"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Code : MainActivity.java
public class MainActivity extends AppCompatActivity {
LinearLayout linearLayout;
private Button btnAddView;
int count = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linearLayout = (LinearLayout) findViewById(R.id.linear_layout);
btnAddView = (Button) findViewById(R.id.btn_add_view);
btnAddView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TextView tv = new TextView(MainActivity.this);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(params);
tv.setText("sample text" + count++);
linearLayout.addView(tv);
}
});
}
}
Output :
Related
I used those code to make 2x2 Image on a GridLayout and it works, but there is one problem, each ImageView has the same ID, -1, so when I use OnClick it does not work. What can I do?
Here the codes
activity_main.xml :
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/gridLayout"
tools:context=".MainActivity"
android:orientation="horizontal"
android:columnCount="2"
android:rowCount="2" />
MainActivity.java :
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridLayout gridLayout = (GridLayout) findViewById(R.id.gridView);
ImageView[][] imageViews = new ImageView[2][2];
for (int i=0;i<2;i++){
for (int j=0;j<2;j++){
imageViews[i][j] = new ImageView(MainActivity.this);
imageViews[i][j].setImageResource(R.mipmap.ic_launcher);
gridLayout.addView(imageViews[i][j]);
}
}
}
}
Your view IDs only need to be positive integers, so could set them like this:
imageViews[i][j].setId(100); // or whatever you prefer
OR you could set a click listener programmaticaly:
// Create the click listener
View.OnClickListener clickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// do what you want
}
};
for (int i=0;i<2;i++){
for (int j=0;j<2;j++){
imageViews[i][j] = new ImageView(MainActivity.this);
imageViews[i][j].setImageResource(R.mipmap.ic_launcher);
imageViews[i][j].setOnClickListener(clickListener);
gridLayout.addView(imageViews[i][j]);
}
}
I use the following codes to create a PopupWindow with dim background by clicking a menu item in Toolbar:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.btn_1:
Log.i(TAG, "Clicked Button 1");
LayoutInflater layoutInflater = (LayoutInflater)getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = layoutInflater.inflate(R.layout.popup_window, null);
final PopupWindow popupWindow = new PopupWindow(popupView, Toolbar.LayoutParams.MATCH_PARENT, Toolbar.LayoutParams.MATCH_PARENT);
Button btnDismiss = (Button)popupView.findViewById(R.id.btn_dismiss);
btnDismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popupWindow.dismiss();
}
});
popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
However, I want to the dim background to exclude the action bars / toolbars. How can I achieve it?
The layout of the PopupView is as follow:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/bac_dim_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#C0000000"
android:visibility="visible" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="1dp"
android:background="#android:color/darker_gray">
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="20dp">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="It's a PopupWindow" />
<Button
android:id="#+id/btn_dismiss"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Dismiss" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
if you want popup window to display with dim background except ToolBar/ActionBar
here i tried setting position of popup window. fetch statusbar & navigation bar height & set Y position to the popup
int actionBarHeight = 0;
View popupView = LayoutInflater.from(getActivity()).inflate(R.layout.popup_, null);
final PopupWindow popupWindow = new PopupWindow(popupView, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
actionBarHeight = getNavigationBarHeight(getActivity(), Configuration.ORIENTATION_PORTRAIT);
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
actionBarHeight = actionBarHeight + getResources().getDimensionPixelSize(resourceId);
}
Button btnDismiss = (Button) popupView.findViewById(R.id.btn_dismiss);
btnDismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popupWindow.dismiss();
}
});
popupWindow.showAsDropDown(popupView, 0, actionBarHeight);
Another way to display popup as you said in comment.Below mentioned you can try
Take one hidden control(TextView) in layout which will be aligned to top. Take the location of the TextView & assigned Y position to popup window
public class MyPopupTest extends Fragment{
public static final String TAG = "MyPopupTest";
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.home_screen_slider, container, false);
}
#Override
public void onViewCreated(final View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.btnSelect).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showPopup(view);
}
});
}
public void showPopup(View view) {
View popupView = LayoutInflater.from(getActivity()).inflate(R.layout.popup_, null);
final PopupWindow popupWindow = new PopupWindow(popupView, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
Button btnDismiss = (Button) popupView.findViewById(R.id.btn_dismiss);
btnDismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popupWindow.dismiss();
}
});
int[] locationOfHiddenTextView = new int[2];
view.findViewById(R.id.hiddenTopTextView).getLocationOnScreen(locationOfHiddenTextView);
//Give Position as a start point for popup
popupWindow.showAsDropDown(popupView, 0, locationOfHiddenTextView[1]);
}
}
XML File of the fragment which is goint to display
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relative_home"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffc699">
<TextView
android:id="#+id/hiddenTopTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:visibility="gone" />
<Button
android:id="#+id/btnSelect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show Popup" />
</RelativeLayout>
I have a solution, but I only test with DialogFragment, not sure it works with dialog or not. I will post it anyway:
1. create your own class which extends DialogFragment.
2. create xml file with your designed dim color:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000" // your designed dim color
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/goto_dialog_title"
android:textColor="#android:color/white"
android:textSize="#dimen/km_25sp"/>
3. Override funcions in your DialogFragment:
private class MyDialog extends DialogFragment{
//override your onCreateView to show your xml here
//override onCreate to show dialog without border and without dim background
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_FRAME, 0);
}
// override to show dim background and avoid dimming actionbar
#Override
public void onResume() {
super.onResume();
int statusBarAndActionBarHeight = 200; //u should calculate yourself
Window window = getDialog().getWindow();
// set size to your dialog --> fullscreen size to show dim bg all screen except action bar and status bar
DisplayMetrics displaymetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
window.setLayout(displaymetrics.widthPixels, displaymetrics.heightPixels - statusBarAndActionBarHeight);
//margin top to avoid dim background above actionbar and status bar
WindowManager.LayoutParams p = window.getAttributes();
p.y = statusBarAndActionBarHeight;
getDialog().getWindow().setGravity(Gravity.TOP);
getDialog().getWindow().setAttributes(p);
}
}
I am trying to add toggle buttons dynamically in a linear layout. I have successfully done this- 2 rows with each row having 2 buttons.
Below is the code for it::
public class MainActivity extends Activity
{
LinearLayout VertLayout;
LayoutInflater inflater;
LinearLayout lnrLay_forXaxis;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialize();
make_seat();
}
private void initialize()
{
VertLayout = (LinearLayout) findViewById(R.id.lnrLyMain);
inflater = (LayoutInflater) this.getLayoutInflater();
}
private void make_seat()
{
try{
for(int y=0;y<2;y++)
{
lnrLay_forXaxis = new LinearLayout(this);
lnrLay_forXaxis.setBackgroundColor(Color.CYAN);
lnrLay_forXaxis.setOrientation(LinearLayout.HORIZONTAL);
LayoutParams LLParams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);
lnrLay_forXaxis.setLayoutParams(LLParams);
for(int x=0;x<2;x++)
{
final View sngl_lnrLay = (View) inflater.inflate(R.layout.lnrly_btn, null);
final ToggleButton btt = (ToggleButton) sngl_lnrLay.findViewById(R.id.ToggleButton01);
btt.setChecked(false);
btt.setText("btn-"+x+y);
btt.setTextOn("btn-"+ x+y+" -ON");
btt.setTextOff("btn-"+x+y);
lnrLay_forXaxis.addView(sngl_lnrLay);
}
VertLayout.addView(lnrLay_forXaxis);
}
}
catch(Exception ex)
{Log.d("exp",ex.toString());}
}
}
in activity_main.xml:
<LinearLayout
android:id="#+id/lnrLyMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCFFCC"
android:orientation="vertical" >
</LinearLayout>
in lnrly_btn.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ToggleButton
android:background="#drawable/btn_toggle_bg"
style="#style/YourThemeName"
android:checked="true"
android:id="#+id/ToggleButton01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp">
</ToggleButton>
</LinearLayout>
Now i want to add some data with each toggle button(think it should be tag i should be using) and add another button to the activity(lets say button-x). So, after selecting few toggle buttons and then clicking on button-x; a toast/Log will appear showing the selected toggle buttons added/tagged values.
How can i do this.
You can do something like that:
Add field to your Activity:
ArrayList<View> toggles = new ArrayList<>();
Then:
for(int y=0;y<2;y++)
{
lnrLay_forXaxis = new LinearLayout(this);
lnrLay_forXaxis.setBackgroundColor(Color.CYAN);
lnrLay_forXaxis.setOrientation(LinearLayout.HORIZONTAL);
LayoutParams LLParams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);
lnrLay_forXaxis.setLayoutParams(LLParams);
for(int x=0;x<2;x++)
{
final View sngl_lnrLay = (View) inflater.inflate(R.layout.lnrly_btn, null);
final ToggleButton btt = (ToggleButton) sngl_lnrLay.findViewById(R.id.ToggleButton01);
Object tag; //your object,int, string ,whatever
//init your tag
btt.setTag(tag);
btt.setChecked(false);
btt.setText("btn-" + x + y);
btt.setTextOn("btn-" + x + y + " -ON");
btt.setTextOff("btn-" + x + y);
toggles.add(btt);
lnrLay_forXaxis.addView(sngl_lnrLay);
}
VertLayout.addView(lnrLay_forXaxis);
}
Button add = new Button(this);
LayoutParams btParams = new LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
btParams.gravity = Gravity.CENTER;
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (View toggle: toggles)
Log.d("TAG", toggle.getTag().toString());
}
});
VertLayout.addView(add, btParams);
I am adding dynamic row with textview in table layout, Also I want x y coordinates of that textview. For that I used view.getLocationOnScreen(loc) method.
But is showing only last item coordinates, I want to show all item coordinates.
This is my source code please help me for that.
Thanks you.
public class MainActivity extends Activity {
TextView tv1, tv2;
TableRow row;
TextView txt;
TableLayout tl;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tl = (TableLayout) findViewById(R.id.tableLayout1);
for (int i = 0; i <= 15; i++) {
row = new TableRow(this);
txt = new TextView(this);
tl.addView(row);
row.addView(txt);
readLocation();
}
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
readLocation();
}
private void readLocation() {
int[] locationOnScreen = new int[2];
txt.getLocationOnScreen(locationOnScreen);
txt.setText(locationOnScreen[0] + " : " + locationOnScreen[1]);
}
}
and my following xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TableLayout
android:id="#+id/tableLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</TableLayout>
</ScrollView>
You shouldn't try to get those coordinates in onCreate method in this way since layout procedures are not yet completed at this point.
Here is a little bit modified demo base on your code:
public class MainActivity extends Activity {
ArrayList<TextView> txt = new ArrayList<TextView>();
TableLayout tl;
Handler _h = new Handler();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tl = (TableLayout) findViewById(R.id.tableLayout1);
for (Integer i = 0; i <= 15; i++) {
TableRow therow = new TableRow(this);
TextView thetxt = new TextView(this);
therow.addView(thetxt);
tl.addView(therow);
txt.add(thetxt);
thetxt.setText("stub");
}
tl.requestLayout();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
protected void onResume() {
super.onResume();
_h.postDelayed(new Runnable() {
#Override
public void run() {
for (Integer i = 0; i <= 15; i++) {
TextView thetxt = txt.get(i);
int[] locationOnScreen = new int[2];
thetxt.getLocationOnScreen(locationOnScreen);
thetxt.setText(locationOnScreen[0] + " : " + locationOnScreen[1]);
}
}
}, 1000);
}
}
The key point is postDelayed in onResume that lets the system to position all views correctly.
I am trying to return layout with chart and some buttons from onCreateView in fragment. I don't know how to combine the two views into one. I can return only the chart or layout without the chart:
public class ChartFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// LineGraph - class which draws the graph using achartengine
final LineGraph lineGraph = new LineGraph();
final GraphicalView chart = lineGraph.getGraphicalView(inflater.getContext());
final View view = inflater.inflate(R.layout.chart, container, false);
Button drawChartButton = (Button) view.findViewById(R.id.button_draw_chart);
drawChartButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// update chart for new data
}
});
return chart; //return the chart only
// return view; // return layout but without the chart
}
}
In activity the following code:
Button chartButton = (Button) findViewById(R.id.button_draw_chart);
chartButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
LinearLayout layout = (LinearLayout) findViewById(R.id.chart);
LineGraph lineGrpah = new LineGraph();
GraphicalView testChart = lineGrpah
.getGraphicalView(SimpleApp.this);
layout.addView(testChart, new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}
});
and xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/chart"
android:layout_width="600dp"
android:layout_height="350dp"
android:layout_margin="15dp" >
</LinearLayout>
<Button
android:id="#+id/button_draw_chart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_draw_chart" />
</LinearLayout>
works properly but I don't know how to do this in fragment.
In onCreateView() just adapt the code you wrote in chartButton's onClick() method, specifically:
view.addView(chart, new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}
});
and then return view.