Android dynamic RelativeLayout overlaps each other - android

I use this code to dynamically print the vaules from my database with a buttonClick-event.
The buttonClick-event to delete the database entry is present inside the a loop.
Here my code:
RelativeLayout rl = (RelativeLayout) findViewById(R.id.relativeLayout3);
final DatabaseHandler dbpin = new DatabaseHandler(this);
// Log.d("Reading: ", "Reading all tasks..");
List<Detail> detail1 = dbpin.getAllDetail();
Button[] button=new Button[1000];
for (Detail cn : detail1) {
String log = cn.getTitle();
final int i = cn.getID();
button[i] = new Button(this);
button[i].setText("Delete");
button[i].setTextSize(10);
button[i].setId(2000 + i);
int width = 80;
int height = 60;
TextView textview = new TextView(this);
textview.setText(log);
textview.setWidth(200);
textview.setTextSize(20);
textview.setPadding( 0, 10, 0, 0);
textview.setId(2000 + i);
if (i == 0) {
RelativeLayout.LayoutParams rlp2 = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
rlp2.addRule(RelativeLayout.ALIGN_PARENT_TOP);
rlp2.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
textview.setLayoutParams(rlp2);
rl.addView(textview);
RelativeLayout.LayoutParams rlp1 = new RelativeLayout.LayoutParams(
width, height);
rlp1.addRule(RelativeLayout.ALIGN_PARENT_TOP);
rlp1.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
button[i].setLayoutParams(rlp1);
rl.addView(button[i]);
} else {
RelativeLayout.LayoutParams rlp2 = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
rlp2.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
rlp2.addRule(RelativeLayout.BELOW, button[i].getId() - 1);
textview.setLayoutParams(rlp2);
rl.addView(textview);
RelativeLayout.LayoutParams rlp1 = new RelativeLayout.LayoutParams(
width, height);
rlp1.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
rlp1.addRule(RelativeLayout.BELOW, button[i].getId() - 1);
button[i].setLayoutParams(rlp1);
rl.addView(button[i]);
}
button[i].setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
Intent myIntent = new Intent(v.getContext(), details.class);
Detail detail = new Detail();
detail.setID(i);
dbpin.deleteDetail(detail);
startActivityForResult(myIntent, 1);
}
});
}
Following the database handler code is, to retrieve all details from database using a loop:
// Getting All detail
public List<Detail> getAllDetail() {
List<Detail> detailList = new ArrayList<Detail>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_DETAIL;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Detail detail = new Detail();
detail.setID(Integer.parseInt(cursor.getString(0)));
detail.setTitle(cursor.getString(1));
detail.setDetail(cursor.getString(2));
// Adding contact to list
detailList.add(detail);
} while (cursor.moveToNext());
}
// return contact list
return detailList;
}
// Deleting single detail
public void deleteDetail(Detail detail) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_DETAIL, KEY_DETID + " = ?",
new String[] { String.valueOf(detail.getID()) });
db.close();
}
At first the layout is normal. Deleting first or the last data row doesn't cause any change, but if a row in the middle is deleted, then the layout overlaps each other.
Please give me suggestions to clear this logical error.

Ok I have understand your problem. Problem is that you are using relative layout as your parent layout in which you are adding all your child relative layouts. Now if you delete your first relative layout then it automatically align with its parent so there will be no problem.
If you delete last relative layout then also not problem occurs.
Now you have align all your relative layout form their above layout so if you delete above one it automatically aligns to its parent.
Solution is simple. Use your parent layout as linear layout so that you dont need to align relative layouts with their above layout. It will automatically arrange in a linear way....
RelativeLayout rl = (RelativeLayout) findViewById(R.id.relativeLayout3); convert this layout in linearlayout in your xml file.
This the code which can help you:
LinearLayout lp = (LinearLayout) findViewById(R.id.LinearLayout1);
// for loop start from here
RelativeLayout rl = new RelativeLayout(getApplicationContext());
RelativeLayout.LayoutParams lp_btn = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
lp_btn.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
Button temp_button = new Button(getApplicationContext());
temp_button.setText("button");
rl.addView(temp_button, lp_btn);
TextView tv = new TextView(getApplicationContext());
tv.setText("bharat");
tv.setBackgroundColor(Color.GREEN);
RelativeLayout.LayoutParams lp_tv = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
lp_tv.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
rl.addView(tv, lp_tv);
lp.addView(rl);
// for loop will end here
I think you should use listview for your purpose it will be better. Anyway this will also work you have to manage relativelayout array and button array for your purpose.

Related

What is the proper way of adding multiple views at runtime without putting too much load on the main thread

I have about 100 views (Buttons,Textviews and ImageButton) in my activity that i create in a for loop. My app runs slow on older versions of android ( 5 and below) and sometimes it does not even load the views.
My question is, what is the proper way of handling such views and loading them without putting too much load on the main thread?
I couldn't use a separate thread since i cant reference UI elements from any other thread than the main one.
Thanks.
for (int i = 0; i < arr.size(); i++) {
String name = arr.get(i).getName();
final int songPath = arr.get(i).getSongPath();
int iconPath = arr.get(i).getIconPath();
RelativeLayout relativeLayout = new RelativeLayout(this);
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
relativeLayout.setLayoutParams(rlp);
buttons[i] = new ImageButton(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 350);
params.setMargins(0, 0, 0, 8);
buttons[i].setLayoutParams(params);
buttons[i].setBackgroundResource(iconPath);
buttons[i].setTag(name + "button");
buttons[i].setId(id++);
TextView emoteName = new TextView(this);
RelativeLayout.LayoutParams textParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
textParams.addRule(RelativeLayout.BELOW, buttons[i].getId());
textParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
textParams.setMargins(20,10,0,0);
emoteName.setText(name.toUpperCase());
emoteName.setId(id++);
emoteName.setTextSize(20f);
emoteName.setLayoutParams(textParams);
Button threedots = new Button(this);
RelativeLayout.LayoutParams threedotsParams = new RelativeLayout.LayoutParams(50, RelativeLayout.LayoutParams.WRAP_CONTENT);
threedotsParams.addRule(RelativeLayout.BELOW, buttons[i].getId());
threedotsParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
threedotsParams.addRule(RelativeLayout.ALIGN_RIGHT,buttons[i].getId());
threedotsParams.setMargins(0,0,0,0);
threedots.setText(getString(R.string.vertical_ellipsis));
threedots.setTextSize(25f);
threedots.setBackgroundColor(Color.TRANSPARENT);
threedots.setLayoutParams(threedotsParams);
final int counterForOnClick = i;
threedots.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ShowDialog(arr.get(counterForOnClick));
}
});
relativeLayout.addView(buttons[i]);
relativeLayout.addView(emoteName);
relativeLayout.addView(threedots);
if (i % 2 == 0) {
leftLayout.addView(relativeLayout);
} else {
rightLayout.addView(relativeLayout);
}
final int index = i;
buttons[i].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playEmoteSound(songPath);
}
});
}
As you said - adding all those views is not the best idea.
From your code, I can see that we are talking about the same views with different data.
You will want to use RecyclerView in order to create a list of the same view.
From the documentation:
If your app needs to display a scrolling list of elements based on large data sets (or data that frequently changes), you should use RecyclerView as described on this page.

Add a parent layout dynamically and a child linearlayout dynamically

I currently have my code that is set up to show one TextView in the parent layout and 3 textviews in the same layout by row. My problem is that the 3 textviews are displaying as 3 different rows when I would like to be set up in the same row as a group. I am thinking I need a child linerlayout but this has not worked for me. The 3 textviews are dynamic and I can't set a certain amount of textviews as the data coming in is dynamic. Here is an example of my code of how my code will display....
Screenshot of 3 textviews in different rows
My code is the following:
//initialize linearlayout
public LinearLayout pickcontainerLayout;
int counter = 0;
//creating a new view by using functions, using keys and values from multimap
for (String key : myMultimap.keySet()) {
ArrayList<SaleOrder> sale = new ArrayList<>();
for (SaleOrder s : myMultimap.get(key)) {
sale.add(s);
}
pickcontainerLayout.addView(containerLayoutfunction(counter, sale.size(), sale, key));
View line = new View(getContext());
line.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,1));
line.setBackgroundColor(Color.rgb(255,255,255));
pickcontainerLayout.addView(line);
counter++;
}
private TextView newSku(int id, String sku) {
TextView skuView = new TextView(getContext());
skuView.setId(id);
skuView.setText("SKU: " + sku);
/*LinearLayout.LayoutParams skuParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
skuView.setLayoutParams(skuParams);*/
skuView.setGravity(Gravity.LEFT);
return skuView;
}
private TextView newqty(int id, String qty) {
TextView qtyView = new TextView(getContext());
qtyView.setId(id);
qtyView.setText("QTY: " + qty);
/*LinearLayout.LayoutParams qtyParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
qtyView.setLayoutParams(qtyParams);*/
qtyView.setGravity(Gravity.CENTER);
return qtyView;
}
private TextView newlocation(int id, String location) {
TextView loc = new TextView(getContext());
loc.setId(id);
loc.setText("Location: " + location);
/*LinearLayout.LayoutParams locParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
loc.setLayoutParams(locParams);*/
loc.setGravity(Gravity.RIGHT);
return loc;
}
private LinearLayout containerLayoutfunction(int parentid, int rowId, ArrayList<SaleOrder> s, String key) {
LinearLayout layout = new LinearLayout(getContext());
layout.addView(newSale(parentid, key));
layout.setOrientation(LinearLayout.VERTICAL);
for (int i = 0; i<rowId;i++) {
//LinearLayout layoutchild = new LinearLayout(getContext());
//layoutchild.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
//layoutchild.setOrientation(LinearLayout.HORIZONTAL);
layout.addView(newSku(rowId,s.get(i).getSku()));
layout.addView(newqty(rowId,s.get(i).getQty()));
layout.addView(newlocation(rowId,s.get(i).getlocation()));
}
return layout;
}
you should wrap the three TextViews in a LinearLayout with horizontal orientation, so the textviews will automatically be on the same row. The container will have FILL_PARENT horizontally as LayuoutParam, while the textview should have WRAP_CONTENT with gravity assigned to LEFT (for the first), CENTER (for the second) and RIGHT (for the third).

Android align views in table row

I am trying to create a table with 2 textviews, edittextview and a button programmatically. My button height is not equal to rest of the elements.
I have tried removing padding and margin but the issue persisted.
Can anyone point out the error or provide a workaround to this.
code is as follows
public void populateItems()
{
// TODO : create uniform table row cells
TableLayout tl = (TableLayout)findViewById(R.id.placeOrderTable);
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.gravity=Gravity.CENTER_HORIZONTAL;
lp.bottomMargin=5;
LayoutParams lpTextView = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
lpTextView.weight=1;
lpTextView.width=0;
lpTextView.bottomMargin=1;
LayoutParams lpEditTextView = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lpEditTextView.weight=1;
lpEditTextView.width=0;
// lpEditTextView.
//lpEditTextView.
lpEditTextView.gravity=Gravity.CENTER_HORIZONTAL;
for(final HashMap<String,String> hm:mTodayItemsHashMap)
{
TableRow tr = new TableRow(getApplicationContext());
tr.setLayoutParams(lp);
TextView tvItemName = new TextView(getApplicationContext());
tvItemName.setLayoutParams(lpTextView);
tvItemName.setBackgroundResource(R.drawable.border_edittext);
tvItemName.setText(hm.get("item_name").toUpperCase());
tvItemName.setEms(10);
tvItemName.setTextColor(Color.BLACK);
tvItemName.setGravity(Gravity.CENTER);
// evItemName.setHint(getString(R.string.item_name));
TextView tvItemPrice = new TextView(getApplicationContext());
tvItemPrice.setLayoutParams(lpTextView);
tvItemPrice.setBackgroundResource(R.drawable.border_edittext);
tvItemPrice.setTextColor(Color.BLACK);
tvItemPrice.setText(hm.get("item_price").toUpperCase());
tvItemPrice.setGravity(Gravity.CENTER);
tvItemPrice.setEms(10);
// evItemPrice.setHint(getString(R.string.item_price));
final EditText evItemQty = new EditText(getApplicationContext());
evItemQty.setLayoutParams(lpTextView);
evItemQty.setInputType(InputType.TYPE_CLASS_NUMBER);
evItemQty.setBackgroundResource(R.drawable.border_edittext);
evItemQty.setTextColor(Color.BLACK);
evItemQty.setGravity(Gravity.CENTER);
evItemQty.setEms(10);
evItemQty.setFilters(new InputFilter[]{ new InputFilterMinMax("1", hm.get("max_qty"))});
// evItemQty.setL
evItemQty.setHint(getString(R.string.max_orders));
Button btnAddToCart=new Button(getApplicationContext());
btnAddToCart.setLayoutParams(lpTextView);
btnAddToCart.setText("Add to Cart");
btnAddToCart.setPadding(0, 0, 0, 0);
// btnAddToCart.setLayoutParams(params);
// btnAddToCart.setBackgroundResource(R.drawable.border_edittext);
btnAddToCart.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// mCart.
item=new Item();
item.setName(hm.get("item_name"));
item.setPrice(hm.get("item_price"));
String temp=evItemQty.getText().toString();
try{
Integer.parseInt(temp);
}
catch(NumberFormatException nfe){
Toast.makeText(getApplicationContext(), "Please specify quantity",Toast.LENGTH_LONG);
return;
}
item.setQty(evItemQty.getText().toString());
if(mCart==null)
mCart=new Cart();
mCart.add(item);
}
});
tr.addView(tvItemName);
tr.addView(tvItemPrice);
tr.addView(evItemQty);
tr.addView(btnAddToCart);
tl.addView(tr,tl.getChildCount()-1, tl.getLayoutParams());
}
}
You will probably want to override the background of the button. You'll get something like this:
This of course means you will not have the curved edges anymore. This can be fixed
as explained in this answer

how can i add and remove element dynamically from linear layout?

LinearLayout linContact = (LinearLayout) mView.findViewById(R.id.linContacts);
LinearLayout.LayoutParams leftGravityparas = new LinearLayout.LayoutParams(0,LayoutParams.WRAP_CONTENT);
LinearLayout.LayoutParams rightGravityParams = new LinearLayout.LayoutParams(30, 30);
for (int i = 0; i < contactList.size(); i++) {
final ClsAdviserData contact = .contactList.get(i);
if (contact.isSelected()) {
linearLayout = new LinearLayout(getActivity());
LinearLayout.LayoutParams linMainparam = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
linearLayout.setBackgroundColor(getActivity().getResources().getColor(R.color.light_grey_backgeound));
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linearLayout.setLayoutParams(linMainparam);
linMainparam.setMargins(0, 10, 0, 0);
leftGravityparas.gravity = Gravity.LEFT;
leftGravityparas.weight = 0.9f;
TextView txtContact = new TextView(getActivity());
txtContact.setTextSize(16);
// txtContact.setBackgroundColor(getActivity().getResources().getColor(R.color.light_grey_backgeound));
txtContact.setLayoutParams(leftGravityparas);
txtContact.setId(i);
leftGravityparas.setMargins(0, 10, 0, 0);
txtContact.setPadding(20, 10, 10, 10);
txtContact.setText(contact.getName());
linearLayout.addView(txtContact, leftGravityparas);
rightGravityParams.gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
rightGravityParams.weight = 0.1f;
final ImageView imgDelContact = new ImageView(getActivity());
imgDelContact.setLayoutParams(rightGravityParams);
imgDelContact.setTag(i);
imgDelContact.setClickable(true);
imgDelContact.setOnClickListener(this);
imgDelContact.setImageResource(R.drawable.ic_close_grey);
linearLayout.addView(imgDelContact, rightGravityParams);
// linContact.setTag(i);
linContact.addView(linearLayout);
imgDelContact.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Toast ==>" + contact.getName() + v.getTag(), Toast.LENGTH_SHORT).show();
// linContact.removeViewAt((Integer) v.getTag());
linearLayout.setVisibility(View.GONE);
// lin.removeViewAt((Integer)v.getTag());
}
});
}
}
I wrote the above code to create the textfields and buttons dynamically; But now I need to remove 2 textfields and a button when the button is clicked. How do I do that?
adding -
After initializing add subview using addView() method declared in LinearLayout
linearLayout.addView(txtContact);
linearLayout.addView(imgDelContact);
Hide -
To hide View ,so that you can get it again whenever required
imgDelContact.setVisibility(View.GONE);
txtContact.setVisibility(View.GONE);
Remove -
Or you can remove if you don't want to use it again.
linearLayout.removeView(txtContact);
linearLayout.removeView(imgDelContact);
To remove any view you can use
aLinearLayout.removeView(view)// to remove particular view
aLinearLayout.removeViewAt(position);// to remove view from particular position
If you are dynamically creating views and you just need to remove all the views just use
aLinearLayout.removeAllViews();
This will clear the layout.

Adding row with 2 columns to Android table layout - 2nd column invisible

I add columns to an android table layout in this way:
public void addWebAction(TableLayout table){
TableRow rowWeb = new TableRow(this);
rowWeb.setWeightSum(1f);
TextView tvWeb = new TextView(this);
tvWeb.setTextSize(18);
tvWeb.setPadding(0, 10, 0, 0);
tvWeb.setText(contact.getWeb());
TableRow.LayoutParams trlp = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 0.8f);
tvWeb.setLayoutParams(trlp);
rowWeb.addView(tvWeb);
ImageButton ibWeb = new ImageButton(this);
ibWeb.setBackgroundColor(Color.TRANSPARENT);
ibWeb.setImageResource(R.drawable.ic_action_search);
ibWeb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(contact.getWeb()));
startActivity(browserIntent);
}
});
trlp.weight = 0.1f;
ibWeb.setLayoutParams(trlp);
rowWeb.addView(ibWeb);
ImageButton abWeb = new ImageButton(this);
abWeb.setBackgroundColor(Color.TRANSPARENT);
abWeb.setImageResource(R.drawable.ic_action_chat);
abWeb.setLayoutParams(trlp);
rowWeb.addView(abWeb);
table.addView(rowWeb);
}
The problem is: If the textview contains a long string the 2nd column is moved out of the screen. In which way did I have to add TableRow Parameters to fix this?
You must give weightSum to table layout and divide edittexts weights two.
You can see the simple example in this link: https://stackoverflow.com/a/9590974/3098590

Categories

Resources