Getting a view's index in a LinearLayout - java

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);
}
});

Related

Plus/Minus button with a counter but counter does not work properly

I have 2 buttons and a TextView to update the counter based on how many times the plus or minus button was pressed.
But, the issue is that: (for example) When I press the "+" button to 4 and goes down to 3 after pressing "-" button. Then, when I try to press "+"(add) button again it jumps up to 5 instead of 4. (i.e. the counter continues adding 1 from when the last time "+" button was pressed.
This is the adapter class where the ImageButtons and TextView listeners are implemented
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
//inflate layout flavor_item.xml
View view = LayoutInflater.from(context).inflate(R.layout.flavor_item, container, false);
//initialize UID views from flavor_item.xml
ImageView imageIv = view.findViewById(R.id.imageIv);
TextView flavorTv = view.findViewById(R.id.flavorTv);
TextView quantityTv = view.findViewById(R.id.quantityTv);
ImageButton minusbutton = (ImageButton) view.findViewById(R.id.minusbutton);
ImageButton plusbutton = (ImageButton) view.findViewById(R.id.plusbutton);
//getting data
DashboardFlavorModel model = modelArrayList.get(position);
String title = model.getTitle();
int image = model.getImage();
String qty = model.getQuantity();
//setting data
imageIv.setImageResource(image);
flavorTv.setText(title);
quantityTv.setText(qty);
//plusbutton listener
plusbutton.setOnClickListener(new View.OnClickListener() {
int count = Integer.parseInt(model.getQuantity());
#Override
public void onClick(View view) {
count++;
model.setQuantity(""+count);
quantityTv.setText(""+count);
}
});
//listener
minusbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int i = Integer.parseInt(model.getQuantity());
if (i > 0) {
i--;
model.setQuantity(""+i);
quantityTv.setText(""+i);
} else{
Snackbar.make(view,"Cannot have < 0 QTY",Snackbar.LENGTH_SHORT).setAction("RETRY", new View.OnClickListener() {
#Override
public void onClick(View view) {
model.setQuantity("0");
quantityTv.setText(model.getQuantity());
}[![enter image description here][1]][1]
}).show();
}
}
});
(Note***) I tried checking the counter using getter and setter to check whether it worked and it did so I have no idea why when pressing "+" after "-" it wouldn't just +1 from the value after "-" button.
try putting
int count = Integer.parseInt(model.getQuantity());
inside onClick for plusbutton onclicklistener

How to remove dynamically created imageview from another button onclick?

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.

Changing the onClickListener of an Imagebutton dynamically without ever leaving the activity

I have an ImageButton with an onClickListener. That sets the "favorite" column of an entry in my database to "1" or "0" and changes the image of the button. What is the best way to refresh the view or activity, so the onClickListener changes dynamically.
If I failed to make myself clear:
Click 1: Update favorite column to 1, change image to ic_star_black_48dp
Click 2: Update favorite column to 0, change image to ic_star_border_black_48dp
Click 3: Update favorite column to 1, change image to ic_star_black_48dp
Click 4: Update favorite column to 0, change image to ic_star_border_black_48dp
All of this without ever leaving the activity.
star.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (cn.getFavorite() == 0) {
star.setImageResource(R.mipmap.ic_star_black_48dp);
db_verladestellen.updatePlace(new Location(cn.getID(), cn.getPlace_id(), cn.getName(), cn.getLongitude(), cn.getLatitude(), cn.getTor(), 1));
}
else{
star.setImageResource(R.mipmap.ic_star_border_black_48dp);
db_verladestellen.updatePlace(new Location(cn.getID(), cn.getPlace_id(), cn.getName(), cn.getLongitude(), cn.getLatitude(), cn.getTor(), 0));
}
}
});
EDIT:
Since you asked, this is the whole class. Below it is the method getAllDBPlaces().
public class UI_Verladestellen extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.verladestellen);
//Initialisation of the database
final DB_Verladestellen db_verladestellen = new DB_Verladestellen(this);
//Saves all entries from the database in a List
List<Location> placeList = db_verladestellen.getAllDBPlaces();
//Generates a button for each entry in the list
for (final Location cn : placeList) {
//Linear Layout for the buttons
final LinearLayout layout = (LinearLayout) findViewById(R.id.verladestellen_liste);
final LinearLayout row = new LinearLayout(this);
row.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
//Favorites-Button
final ImageButton star = new ImageButton(this);
star.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
if (cn.getFavorite() == 0) {star.setImageResource(R.mipmap.ic_star_border_black_48dp);}
else {star.setImageResource(R.mipmap.ic_star_black_48dp);}
star.setId(cn.getID());
row.addView(star);
star.setPadding(50,50,50,50);
star.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (cn.getFavorite() == 0) {
star.setImageResource(R.mipmap.ic_star_black_48dp);
db_verladestellen.updatePlace(new Location(cn.getID(), cn.getPlace_id(), cn.getName(), cn.getLongitude(), cn.getLatitude(), cn.getTor(), 1));
}
else{
star.setImageResource(R.mipmap.ic_star_border_black_48dp);
db_verladestellen.updatePlace(new Location(cn.getID(), cn.getPlace_id(), cn.getName(), cn.getLongitude(), cn.getLatitude(), cn.getTor(), 0));
}
}
});
//Location-Button
Button place = new Button(this);
place.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
place.setText(cn.getName());
place.setId(cn.getID());
row.addView(place);
row.setId(cn.getID());
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) place.getLayoutParams();
params.weight = 1.0f;
place.setLayoutParams(params);
place.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openMap(cn.getID());
}
});
layout.addView(row);
}
}
//Methode zum öffnen der Map in MainActivity. Übermittelt die ID des Buttons, von dem die Methode aufgerufen wird.
//Diese ID ist identisch mit der ID des Ortes in der Datenbank, den der Button repräsentiert.
public void openMap(int view) {
Intent intent = new Intent(UI_Verladestellen.this, UI_MainActivity.class);
intent.putExtra("findLocation", view);
startActivity(intent);
}
}
getALLDBPlaces:
public List<Location> getAllDBPlaces() {
List<Location> placeList = new ArrayList<Location>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_DB_VERLADESTELLEN_Eintrag;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Location location = new Location();
location.setID(Integer.parseInt(cursor.getString(0)));
location.setPlace_id(cursor.getString(1));
location.setName(cursor.getString(2));
location.setLongitude(cursor.getString(3));
location.setLatitude(cursor.getString(4));
location.setTor(cursor.getString(5));
location.setFavorite(cursor.getInt(6));
// Adding contact to list
placeList.add(location);
} while (cursor.moveToNext());
}
// return contact list
return placeList;
}
Well after you edited your question, my answer will be different.
First of all, you should check for Adapter implementation.
It will be easier to handle your scenario and be way more effective.
But then you should try to implement it yourself and come agian if you face any issues.

Having trouble removing and then adding views programatically to FrameLayout

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

Android tableview with dynamic numbers columns and rows

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())));
}
}

Categories

Resources