I have created an ImageView dynamically like below image.It works fine. Now I want to remove view when top cross ImageView is clicked. When I click, it crashes .Please help how to achieve it.
here is what i have done
private void postImage(List<Uri> urilist) {
for(int i=0; i< urilist.size(); i++) {
imgView = new ImageView(getActivity());
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(150, 150);
lp.setMargins(20,10,20,10);
imgView.setLayoutParams(lp);
imgView.setId(i);
Log.d("uri list in loop",""+urilist.get(0));
Glide.with(getActivity())
.load(urilist.get(i))
.into(imgView);
layout.addView(imgView);
imgView1 = new ImageView(getActivity());
LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(50, 50);
lp1.setMargins(0,5,1,80);
imgView1.setLayoutParams(lp1);
imgView1.setId(i);
Log.d("uri list in loop",""+urilist.get(0));
Glide.with(getActivity())
.load(R.drawable.ic_action_cross)
.into(imgView1);
layout.addView(imgView1);
}
imgView1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
layout.removeViewAt(v.getId());
}
});
}
If it is because of the index (which definitely will crash in deletion of the 2nd item) then you can try below
imgView1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ViewGroup parentView = (ViewGroup) v.getParent();
parentView.removeView(v);
}
});
Note: You should not set id of two views as same. Rather use some mathematical formula.
I mean #shakac, you can try like that;
for(int i = 0; i<layout.getChildCount(); i++)
{
if (layout.getChildAt(i).getId() == v.getId()){
layout.removeView(layout.getChildAt(i));
break;
}
}
But as I said on the comment, you will remove the cross button like that.
Related
So I have a LinearLayout set up in my XML file, and I dynamically add a bunch of CardViews to it through code upon startup of my activity. How can I make it so that when I click on any of the CardViews, I am able to obtain its position?
I tried setting up on an onClickListener for the LinearLayout, as well as an OnClickLIstener for each individual card, but couldn't find a way to obtain the index of the card that was clicked.
I'd really like to know where to put the onClickListener, and how to obtain the position that was clicked so that I can start a new activity based on what was clicked.
Here is my code:
private LinearLayout sLinearLayout;
private CardView[] cardViews;
private Workout[] workouts;
private ViewGroup.LayoutParams params;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.saved_workouts);
Intent intent = getIntent();
Parcelable[] parcelableArrayExtra = intent.getParcelableArrayExtra(MainActivity.EXTRA_WORKOUTS);
workouts = new Workout[parcelableArrayExtra.length];
System.arraycopy(parcelableArrayExtra, 0, workouts, 0, parcelableArrayExtra.length);
sLinearLayout = findViewById(R.id.viewList);
// Set the CardView layoutParams
params = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
populateCardViews();
populateLayout();
}
//TODO: this method will populate the linear layout, filling the list.
private void populateLayout() {
for (CardView cardView : cardViews) {
sLinearLayout.addView(cardView);
}
}
//TODO: this method will fill up the CardViews array with an array of workouts.
private void populateCardViews() {
cardViews = new CardView[workouts.length];
for(int i = 0; i < workouts.length; i++) {
CardView card = new CardView(this);
card.setClickable(true);
card.setLayoutParams(params);
// Set CardView corner radius
card.setRadius(9);
// Set cardView content padding
card.setContentPadding(15, 15, 15, 15);
// Set a background color for CardView
card.setCardBackgroundColor(Color.BLUE);
// Set the CardView maximum elevation
card.setMaxCardElevation(50);
// Set CardView elevation
card.setCardElevation(25);
// Initialize a new TextView to put in CardView
TextView tv = new TextView(this);
tv.setLayoutParams(params);
tv.setText("Workout WorkTime: " + workouts[i].getWorkTime());
tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 30);
tv.setTextColor(Color.WHITE);
card.setTag(workouts[i].getWorkTime());
card.addView(tv);
cardViews[i] = card;
}
}
I think you can setOnClickListener for each individual card. The index of clicked card is i
for (int i = 0; i < workouts.length; i++) {
...
final int finalI = i;
card.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("TAG", "You click at card: " + finalI);
}
});
}
I not good to add so much layout programmatically. You can use a recycler view and an adapter to show a list of items. You can read this: https://developer.android.com/guide/topics/ui/layout/recyclerview
By the way, in your case: when you create a Cardview, just add onClickListener to it and the index of your Cardview is the index of it in Cardview list.
CardView cardView = new CardView(this);
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//handle click here
}
});
See if this works.
cardview.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int index = linearLayout.indexOfChild(v);
}
});
I have a set of ImageView in which some of them are red colored blink for some time like below.
I want to do that ,When I'm click on colored blinked imageViews it change as tic mark and when I'm click non blinked imageViews it change as cross mark.
My issue is my current code only tic the one imageview and all other imageViews are cross marked.
So how to make tic mark more than one ImageView.
Here is my code:
org_id = new int[]{R.id.img1_1, R.id.img1_2, R.id.img1_3, R.id.img1_4};
all = new int[]{R.id.img1_1, R.id.img1_2, R.id.img1_3, R.id.img1_4};
Random random = new Random();
for(int j=0;j<2;j++) {
id = all[random.nextInt(all.length)];
ObjectAnimator animator = ObjectAnimator.ofInt(findViewById(id), "backgroundResource", R.drawable.new_stateimg, R.drawable.org_state).setDuration(2000);
Toast.makeText(Game.this, "index" + findViewById(id), Toast.LENGTH_LONG).show();
animator.setEvaluator(new ArgbEvaluator());
animator.start();
for (int i=0; i < org_id.length; ++i) {
final int btn = org_id[i];
findViewById(btn).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if ((findViewById(id)).equals(findViewById(btn)))
{
findViewById(id).setBackgroundResource(R.drawable.correct);
} else {
Toast.makeText(Game.this, "wrong", Toast.LENGTH_SHORT).show();
findViewById(btn).setBackgroundResource(R.drawable.cross);
}
}
});
}
}
Compare your id like
if (id.getId() == btn.getId())
Do it in your code.
public void onClick(View view) {
ImageView imgView = (ImageView)view; //edited
if(imgView.getDrawable().getConstantState().equals
(getResources().getDrawable(R.drawable.correct).getConstantState()))
imgView.setBackgroundResource(R.drawable.incorrect);//set here you incorrect image which you want.
else
imgView.setBackgroundResource(R.drawable.correct);//set here your correct image
}
I am having trouble removing a LinearLayout from a FrameLayout, to then add a new LinearLayout that is populated with EditText generated programatically.
The first time that the view is loaded, I catch a reference to the FrameLayout using findViewById(), and then I make a new LinearLayout programmatically and add a number of EditText to it.
It looks like this
formPlace = (FrameLayout) findViewById(R.id.form_place);
LinearLayout linearView = new LinearLayout(this);
linearView = makeEditText(arrayItems,category);
linearView.setBackgroundColor(Color.GRAY);
linearView.setOrientation(LinearLayout.VERTICAL);
formPlace.addView(linearView);
Next is the function that makes the EditTexts:
private LinearLayout makeEditText(ArrayList<String[]> arrayString, int position){
LinearLayout view = new LinearLayout(this);
arrayInputs = new ArrayList<>();
String[] arrayHints = arrayString.get(position);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
for (int i=0;i<arrayHints.length;i++){
EditText editText = new EditText(this);
Log.i("myApp","tantas veces" + i);
editText.setId(i);
editText.setTextColor(Color.BLACK);
editText.setHint(arrayHints[i]);
editText.setHintTextColor(Color.GRAY);
editText.setLayoutParams(params);
view.addView(editText);
arrayInputs.add(editText);
}
LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
buttonParams.gravity = Gravity.RIGHT;
android.widget.Button save = new android.widget.Button(this);
save.setText("Guardar");
save.setLayoutParams(buttonParams);
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("myApp", "guardar");
saveClicked(category);
}
});
view.addView(save);
android.widget.Button cancel = new android.widget.Button(this);
cancel.setText("cancelar");
cancel.setLayoutParams(buttonParams);
cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("myApp", "cancelar");
cancelClicked();
}
});
view.addView(cancel);
return view;
}
Then, when a spinner event is called, I catch the reference of the FrameLayout and pass .removeAllViews(). This works as intended, and my pevious view is deleted. The problem comes when I try to add new views to the FrameLayout in the makeEditText line:
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, final int position, long id) {
if(firstTime==false) {
FormActivity.this.formPlace.removeAllViews();
LinearLayout auxLinearView = new LinearLayout(FormActivity.this);
auxLinearView = makeEditText(arrayItems, position);
FormActivity.this.formPlace.addView(auxLinearView);
}
firstTime =false;
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
What happens is that the old view is deleted but the new view is not set properly. It only shows 1 element of the 4 is intended to show, and the buttons that I create programmatically don't show at all. And my FrameLayout occupies all the remaining space in my screen, even though is set to wrap content. What it implies is that the view is not behaving as it should.
EDIT:
Here are some Screenshots
Here is how it looks before removeAllViews():
https://dl.pushbulletusercontent.com/tExAXJexe4BfG5sGuKvb1RFtGOFd51nE/Screenshot_2015-05-04-17-54-18.png
Here is how it looks after adding the views to the FrameLayout:
https://dl.pushbulletusercontent.com/JM72D3ZrLwTh0YC9g7PODREyOfCj667P/Screenshot_2015-05-04-17-54-25.png
This is actually a memory training app, with matrix of squares wich flips to their other side and than back to first side. And user need to click on squares that flipped. You know what I mean?
Something like that.
What I need is that sizes of the matrix would change dynamically. If user have been passed one level of complexity (matrix size is 4x4 for example), then matrix size would grow (5x5 for example), and if not then matrix size would get smaller (3x3 for example). I hope that's clear, and if not - sorry, English is not my native language =)
So if I would do it from code this would not be a problem. I would use ViewFlipper with some transition animation and create TableView with sizes that I want with inflater or something like that (or directly from code without using xml at all). And then adding it to ViewFlipper from code.
But somehow I don't like that idea.
Then next idea come into my mind. To do ViewFlipper with all possible tableviews in it and then just showNext(); or showPrevious(); depending on what user have done. But in this case XML would be of very great size.
So maybe someone knows the another way to do it?
i suggest you to look view-pager-example,
using viewflipper showNext(); or showPrevious(); you had to download all data at the same time, but using fragmen, you can load only specific data assoiated with fragment.
you can change the view on every fragment like below
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new DetailFragment();
case 1:
return new ImageFragment(R.drawable.ic_launcher);
case 2:
return new ImageFragment(R.drawable.thumb);
default:
return null;
}
}
[EDIT - For checking view in listener]
public class LoginExampleImplements extends Activity implements OnClickListener {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
btn3.setOnClickListener(this);
btn4.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(v==btn1) {
} else if(v==btn2) {
} else if(v==btn3) {
} else if(v==btn4) {
}
}
}
[EDIT 2]
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
LinearLayout1 = (LinearLayout) findViewById(R.id.LinearLayout1);
for (int i = 0; i < 30; i++) {
button = new Button(getApplicationContext());
button.setId(i);
button.setOnClickListener(this);
LinearLayout1.addView(button);
}
}
#Override
public void onClick(View v) {
Button b = (Button)v;
b.getId()
// check clikedId
}
[EDIT 3]
public class MainActivity extends Activity implements OnClickListener{
ImageView img;
LinearLayout LinearLayout1;
LinearLayout.LayoutParams layoutParams;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout1 = (LinearLayout) findViewById(R.id.ln1);
layoutParams = new LinearLayout.LayoutParams(100, 100);
for (int i = 0; i < 30; i++) {
img = new ImageView(getApplicationContext());
img.setId(i);
img.setTag(i);
layoutParams.setMargins(10, 10, 10, 10);
img.setLayoutParams(layoutParams);
img.setBackgroundColor(Color.RED);
img.setPadding(10, 10, 10, 10);
img.setOnClickListener(this);
LinearLayout1.addView(img);
}
}
#Override
public void onClick(View v) {
ImageView b = (ImageView)v;
b.setBackgroundColor(Color.BLUE);
b.setImageLevel(Integer.valueOf(String.valueOf(b.getTag())));
}
}
Can anyone please guide me on how to setOnClickListener for the TextViews that are generated dynamically.
I have few buttons in my app.Now when a particular button is clicked than some specific text elements are retrieved from the database based on the the number of elements returned corresponding TextViews are generated in order to display the retrieved text elements.
Now the problem that i'm having is that i don't know how to set onClickListner for the dynamically generated TextViews.Following is the piece of code where i'm creating my TextViews.Please guide me on what should i do.thank you
public void onClick(View v) {
switch (v.getId()) {
case R.id.imageButton1:
catagory = "General";
IndependentDB genData = IndependentDB.getInstance();
genData.open(this);
ArrayList<TextHolder> genList = new ArrayList<TextHolder>();
genList = genData.getAllTextFromGenT();
genData.close();
x = genList.size();
String xstr = new StringBuilder().append(x).toString();
System.out.println(xstr);
mainText = new TextView[x];
textLayout = new LinearLayout[x];
llseperator = new LinearLayout[x];
textLayoutContainer
.setBackgroundResource(R.color.dark_navy_blue);
if (!genList.isEmpty()) {
for (int i = 0; i < x; i++) {
TextHolder firstOne = genList.get(i);
String text = firstOne.getText();
mainText[i] = new TextView(this);
mainText[i].setId(i);
mainText[i].setText("Text");
mainText[i].setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
mainText[i].setTextSize(25);
mainText[i].setGravity(Gravity.CENTER);
mainText[i].setText(text);
mainText[i].setTextColor(0xFFFFFFFF);
mainText[i].setClickable(true);
mainText[i].setOnClickListener(this);
llseperator[i] = new LinearLayout(this);
llseperator[i].setId(i);
llseperator[i].setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
llseperator[i].setGravity(Gravity.CENTER);
llseperator[i]
.setBackgroundResource(R.drawable.tv_seperator);
textLayout[i] = new LinearLayout(this);
textLayout[i].setId(i);
textLayout[i].setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
textLayout[i].setGravity(Gravity.CENTER);
textLayout[i].addView(mainText[i]);
textLayoutContainer.addView(textLayout[i]);
textLayoutContainer.addView(llseperator[i]);
}// End of for
}// End of If
break;}
You already have onClick() method in Activity class (implemented View.setOnClickListener) so I suggest you to create a new class which implements View.setOnClickListener interface to handle click of TextView.
Try,
class TextClick implements View.setOnClickListener {
#Override
public void onClick(View view) {
TextView tx=(TextView) view;
...
}
}
and set click listener,
TextClick click=new TextClick();
for (int i = 0; i < x; i++) {
TextHolder firstOne = genList.get(i);
String text = firstOne.getText();
mainText[i] = new TextView(this);
mainText[i].setOnClickListener(click);
...
}
It's the same setting on click listeners regardless of if the view was dynamically generated.
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
dosomething();
}
});
For example. you have a List tvs to store your TextView Objects created by the db result. What you should do is like this:
for(int i =0;i<tvs.count;i++){
tvs.get(i).setOnClickListener(new OnClickListener(){
...
})
}