问题
I'm developing an app which on start up will show a pre-defined layout like Image(1) in below screenshot.
Now onclick of a button, I want to dynamically add another view like Image(2) in below screenshot to existing view resulting into some like Image(3) in below screenshot.
If onclick is clicked again, Image(2) will be added to existing view resulting into something like Image(4).
How do I achieve this?
By searching, I found that it required something like LayoutInflater.addView()
like this or LinearLayout.addView()
like this.
But I don't know what exactly to use in my case.
Also, I'm not trying to add just a single view on button click, but a group of certain views like imageview, 2 textviews,etc. as shown in Image(2).
Any help appreciated.
Edit 1:
I tried something like this: activity_main.xml
<RelativeLayout 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" >
<LinearLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
android:onClick="addViews"
android:text="Add" />
</RelativeLayout>
MainActivity.java
public class MainActivity extends Activity {
LinearLayout main;
int count = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
main = (LinearLayout) findViewById(R.id.main);
}
public void addViews(View view) {
LayoutParams lparams = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
Button btn = new Button(this);
btn.setLayoutParams(lparams);
count++;
btn.setText("Hello World : " + count);
main.addView(btn, count);
}
}
It yields something like this:
Now, how do I recognize which button is clicked?
回答1:
You can do a lot of things to get that working, but the best approach could be using ListView
and ArrayAdapter
Create a class that extends ArrayAdapter<Integer>
. There, create a interface
to create a Listener.
public interface OnListButtonItemClickedListener{
public int onListButonItemClicked(int position);
}
Define a private OnListButtonItemClickedListener
on your ArrayAdapter
, and create a public setter.
private OnListButtonItemClickedListener listener;
public void setOnListButtonItemClickedListener(OnListButtonItemClickedListener listener){
this.listener = listener;
}
Define a button inside a Layout in XML. Something like this will do:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dip" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Create a inner ViewHolder
class inside your ArrayAdapter
class like this:
private class ViewHolder{
public Button b;
}
Override getView
and create something like this:
@Override
public View getView(final int position, View convertView, ViewGroup parent){
ViewHandler vh;
if (convertView == null){
convertView = View.inflate(getContext(), R.layout.your_layout, null);
vh = new ViewHolder();
vh.b = (Button) convertView.findViewById(R.id.button1);
convertView.setTag(vh);
} else {
vh = (ViewHolder) convertView.getTag();
}
vh.b.setText(String.valueOf(getItem(i).intValue()));
vh.b.setOnClickListener(new OnClickListener(){
public void onClick(View v){
if (listener != null){
listener.onListButonItemClicked(getItem(position).intValue());
}
}
});
return convertView;
}
Set the adapter to a ListView, and when you want to add a new one, just do this:
adapter.add(i);
adapter.notifyDataSetChanged();
回答2:
So, you can inflate a view from an XML layout from an Activity
like this
View v = View.inflate(this, R.layout.whatever, null);
and then you can add it to your LinearLayout
like this:
linearLayout.addView(v);
If you want to access the inner views in your items, you can do it like this:
TextView textView = (TextView) v.findViewById(R.id.textView1);
So, you have to define that group of views in a XML layout, inflate it, manipulate its views as you need, and then add it to your LinearLayout
.
Note that you'll need your LinearLayout orientation to be vertical or it won't work as you need.
回答3:
Maybe you can try this
- Create a custom view that extends LinearLayout, orientation: vertical.
- Create another custom view, this view will be the "row". This view is the container of the image, text in bold and text below.
- In the first custom view that extends linearLayout, you can addView(View v) and pass the other custom view, the row.
Am I clear? It is something similar that adapter and listview works.
回答4:
I don't know if this fits whatever your app's purpose is, but try using a ListView
with an ArrayAdapter
. You will begin with an empty ListView
, as defined in XML, then add items to a connected ArrayAdapter
in code. Each time the button is pressed, you can add an image into the ArrayAdapter
and call .notifyDataSetChanged()
. This should stack them just as shown in your images above. You can also use a secondary LinearLayout
to group items.
EDIT:
To determine which button is clicked you simply reference the View
passed to your addViews(View v)
method. You can either switch on the id:
public void addViews(View v){
int id = v.getId();
switch(id){
case R.id.id1:
//do something
case R.id.id2:
//do something
}
}
Or you can get the text from the button in a similar manner by using:
public void addViews(View v){
Button b = (Button)v; //make sure you know that it will be a button
String s = b.getText().toString();
switch(s){
case "test case 1":
//do something
case "test case 2":
//do something
}
}
If you aren't sure how many buttons there will be, I would suggest using the strings method. If the buttons won't have names that are convenient to parse in this manner, store references to the buttons as keys in a HashMap and use a String as the value. You can then plug in the button, get the string and do whatever is needed.
来源:https://stackoverflow.com/questions/16942486/add-imageview-dynamically-to-existing-view