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]);
}
}
Related
To assign data of an ArrayList<String> alKategorien to a spinner auswahl_kategorie, I am using this snippet:
ad = new ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
alKategorien);
ad.setDropDownViewResource(
android.R.layout
.simple_spinner_dropdown_item);
auswahl_kategorie.setAdapter(ad);
I tried to reuse the ArrayAdapter by phrasing it like
if (ad == null) {
ad = new ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
alKategorien);
ad.setDropDownViewResource(
android.R.layout
.simple_spinner_dropdown_item);
auswahl_kategorie.setAdapter(ad);
}
else
{
ad.clear();
ad.addAll(alKategorien);
ad.notifyDataSetChanged();
}
Yet unless ad is null, this yields an empty spinner.
How do I reuse the ArrayAdapter properly?
I have just made a very simple sample.
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:padding="10dp"
tools:context=".MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 1"
android:id="#+id/bt1" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 2"
android:id="#+id/bt2" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 3"
android:id="#+id/bt3" />
<Button
android:id="#+id/btGetSpinnersValues"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Get Spinners Values" />
</LinearLayout>
item_schreiben.xml:
<?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"
android:padding="10dp">
<TextView
android:id="#+id/tvSample"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Spinner
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/auswahl_kategorie" />
</LinearLayout>`
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private final int NO_OF_ITEMS = 3;
Button bt1, bt2, bt3, btGetSpinnersValues;
//Spinner auswahl_kategorie;
ArrayList<String> alKategorien = new ArrayList();
ArrayList<Integer> alDynamicChildren = new ArrayList();
ArrayAdapter ad;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout rootLayout = findViewById(R.id.rootLayout);
bt1 = findViewById(R.id.bt1);
bt2 = findViewById(R.id.bt2);
bt3 = findViewById(R.id.bt3);
btGetSpinnersValues = findViewById(R.id.btGetSpinnersValues);
alKategorien.add("a");
alKategorien.add("b");
alKategorien.add("c");
alKategorien.add("d");
alKategorien.add("e");
setSpinnerAdapter();
for (int i = 0; i < NO_OF_ITEMS; i++) {
View dl_item_schreiben = getLayoutInflater().inflate(R.layout.item_schreiben, null);
rootLayout.addView(dl_item_schreiben);
alDynamicChildren.add(rootLayout.indexOfChild(dl_item_schreiben));
TextView textView = dl_item_schreiben.findViewById(R.id.tvSample);
textView.setText("Spinner " + (i + 1));
Spinner auswahl_kategorie = dl_item_schreiben.findViewById(R.id.auswahl_kategorie);
auswahl_kategorie.setAdapter(ad);
auswahl_kategorie.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
bt1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
alKategorien.clear();
alKategorien.add("A");
alKategorien.add("B");
alKategorien.add("C");
alKategorien.add("D");
alKategorien.add("E");
ad.notifyDataSetChanged();// or setSpinnerAdapter();
}
});
bt2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
alKategorien.clear();
alKategorien.add("1");
alKategorien.add("2");
alKategorien.add("3");
alKategorien.add("4");
alKategorien.add("5");
ad.notifyDataSetChanged();// or setSpinnerAdapter();
}
});
bt3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
alKategorien = new ArrayList<>();
alKategorien.add("A");
alKategorien.add("B");
alKategorien.add("C");
alKategorien.add("D");
alKategorien.add("E");
setSpinnerAdapter();
}
});
btGetSpinnersValues.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String msg = "";
LinearLayout parent = (LinearLayout) view.getParent();
for (int i = 0; i < NO_OF_ITEMS; i++) {
Spinner auswahl_kategorie = parent.getChildAt(alDynamicChildren.get(i)).findViewById(R.id.auswahl_kategorie);
msg += "Spinner " + (i +1) + ": " + auswahl_kategorie.getSelectedItem().toString() + "\n";
}
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
});
}
private void setSpinnerAdapter() {
if (ad == null) {
ad = new ArrayAdapter(this, android.R.layout.simple_spinner_item, alKategorien);
ad.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//auswahl_kategorie.setAdapter(ad);
} else {
//ad.clear();
//ad.addAll(alKategorien);
ad.notifyDataSetChanged();
}
}
}
I tested the code and spinner changed content for bt1/bt2 clicked. But after bt3 clicked, no more change.
First, when the adapter is created, it is set with alKategorien as the data list, so call ad.clear() just clear alKategorien and ad.addAll(alKategorien); add back an empty list. Therefore those two lines should be removed.
Second, data list cannot be created again (i.e. = new ArrayList<>() and so no more change after bt3 clicked) but can be modified (clear, add, remove) because it acts like a linkage between activity and adapter. If data list is created again by new, then the adapter needs to be created again as linkage broken. There may be other conditions that can break the linkage. Since the code that I mentioned in first point is removed, so issue should be caused by the way of modifying data list which is not shown in the snippet.
Is it possible to duplicate an element, (such as a spinner that I already have on my activity screen) by pressing a button? And I'll be able to use both spinners and add as many as I want?
This code show you how to create spinner programmatically and add it to a LinearLayout.
You can call makeSpinner method and get a duplicated spinner.
Then add it to your ViewGroup as a child view by calling addView method.
Tip: you should store reference of added spinner for accessing them later. I stored them in mSpinners.
public class MainActivity extends AppCompatActivity {
private LinearLayout mLinearLayout;
private ArrayList<Spinner> mSpinners; // to hold reference of added spinner for reading purposes
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSpinners = new ArrayList<>();
mLinearLayout = findViewById(R.id.my_linearLayout);
mLinearLayout.addView(makeSpinner()); // First spinner
Button duplicateSpinner = findViewById(R.id.bt_duplicate);
duplicateSpinner.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Spinner spinner = makeSpinner();
mLinearLayout.addView(spinner); // Add another spinner
}
});
Button getSpinner = findViewById(R.id.bt_getSpinner);
getSpinner.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
for (int i = 0; i < mSpinners.size(); i++) { // Read all spinners
Spinner spinner = mSpinners.get(i);
Log.i("TAG", spinner.getSelectedItem().toString());
}
}
});
}
private Spinner makeSpinner() {
Spinner spinner = new Spinner(this, Spinner.MODE_DROPDOWN);
// Setup layout
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
spinner.setLayoutParams(layoutParams);
// Prepare data
ArrayList<String> data = new ArrayList<>(); // change it based on your code
data.add("Item 1");
data.add("Item 2");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, data);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
mSpinners.add(spinner); // store it
return spinner;
}
}
This is the activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/my_linearLayout"
android:orientation="vertical"
tools:context="com.khahani.app.stack.MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/bt_duplicate"
android:text="Duplicate"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/bt_getSpinner"
android:text="Get Selected Item"/>
</LinearLayout>
Enjoy it.
In my main activity java code file, I'm adding a new view with this method:
public void AddNewView(View view) {
Intent intent = new Intent(this, DisplayNewView.class);
startActivity(intent);
}
This uses a class called DisplayNewView which has this method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TableLayout.LayoutParams tlp = new TableLayout.LayoutParams(
TableLayout.LayoutParams.WRAP_CONTENT,
TableLayout.LayoutParams.WRAP_CONTENT);
LayoutInflater inflater = getLayoutInflater();
View view;
view = inflater.inflate(R.layout.activity_display_view, null);
TextView tv = (TextView) view.findViewById(R.id.myViewLabel);
tv.setTextSize(40);
addContentView(view,tlp);
}
So this sucessfully adds the view.
But now, in the same xml resource file that this view uses, I have a button that is supposed to remove this view. This button is also in the same DisplayNewView java code file.
It looks like this:
public void removeView(View view) {
ViewGroup vg = (ViewGroup)(view.getParent());
vg.removeView(view);
}
But when I click on the button, nothing happens. I also don't see any errors in the debugger console in Android Studio.
From my web searches, it looks like I'm trying to remove the view in the right way.
Is there anything I'm missing?
Thanks!
I've recreated your problem and i don't see any errors in presented code. From what i understand you should have something similar to this:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonadd = (Button) findViewById(R.id.addButton);
buttonadd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AddNewView(view);
}
});
}
public void AddNewView(View view) {
Intent intent = new Intent(this, DisplayNewView.class);
startActivity(intent);
}
}
public class DisplayNewView extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TableLayout.LayoutParams tlp = new TableLayout.LayoutParams(
TableLayout.LayoutParams.WRAP_CONTENT,
TableLayout.LayoutParams.WRAP_CONTENT);
LayoutInflater inflater = getLayoutInflater();
View view;
view = inflater.inflate(R.layout.activity_display_view, null);
TextView tv = (TextView) view.findViewById(R.id.myViewLabel);
tv.setTextSize(40);
Button buttondelete = (Button) view.findViewById(R.id.deleteButton);
buttondelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
removeView(view);
}
});
addContentView(view, tlp);
}
public void removeView(View view) {
ViewGroup vg = (ViewGroup) (view.getParent());
vg.removeView(view);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.stackquest.MainActivity">
<Button
android:id="#+id/addButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add">
</Button>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_display_new_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.stackquest.DisplayNewView">
<TextView
android:id="#+id/myViewLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:id="#+id/deleteButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delete">
</Button>
</LinearLayout>
Clicking on delete button should delete the button view. If you wish to delete all views you can use vg.removeAllViews(); and as others have mentioned why create new intent for dynamically manipulating views?
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 :
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.