How I can select multiples rows in a recycleview correctly ?
I see this example : https://github.com/kiddBubu/RecyclerViewDemo but is so bat because when move up or down screen value disappear or change or assing position to other row, so bad.
I try show more content of the row.
Example :
Row 1 (uncollapsed)
Row 2 (uncollapsed) - > click - > (collapsed) add + padding or margin
Row 3 (uncollapsed)
.
.
Row x (uncollapsed)
But when I try move list up or down the value selected is randomly and others views change automatically, I don't know why, ListView, RecycleView are equals...
I know how do with listviews normals with "tags" (but also is bad)
I don't want "expandablelistview".
Any help ?
Update
I want this efect : http://i.stack.imgur.com/fuFFl.png
I have not found anything, not a complete example in google
Code :
I tried 4 or 5 methods, this is the first
boolean [] check; check = new Boolean[Fragment2.recyclerView.size()];
Arrays.fill(array, Boolean.FALSE);
.
.
.
public class ViewHolder extends RecyclerView.ViewHolder {
// l1
public TextView text1,text2,text3,text4;
LinearLayout imgLayout,l1;
// l2
public TextView text5,text6,text7;
LinearLayout l2;
public ViewHolder(final View itemView) {
super(itemView);
l1 = (LinearLayout) itemView.findViewById(R.id.l1);
imgLayout = (LinearLayout) itemView.findViewById(R.id.imgLayout);
text1 = (TextView) itemView.findViewById(R.id.text1);
text2 = (TextView) itemView.findViewById(R.id.text2);
text3 = (TextView) itemView.findViewById(R.id.text3);
text4 = (TextView) itemView.findViewById(R.id.text4);
l2 = (LinearLayout) itemView.findViewById(R.id.l2);
text5 = (TextView) itemView.findViewById(R.id.text5);
text6 = (TextView) itemView.findViewById(R.id.text6);
text7 = (TextView) itemView.findViewById(R.id.text7);
int itemPosition = Fragment2.recyclerView.getChildPosition(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!check[itemPosition]) {
l1.setVisibility(View.VISIBLE);
l1.setEnabled(true);
check[itemPosition] = true;
l2.setVisibility(View.GONE);
l2.setEnabled(false);
} else {
l1.setVisibility(View.GONE);
l1.setEnabled(false);
check[itemPosition] = false;
l2.setVisibility(View.VISIBLE);
l2.setEnabled(true);
}
}
The RecyclerView connects a data structure like an ArrayList via Adapter. Upon an update of the ArrayList, your RecyclerView's View objects should change state.
If I were to update multiple rows in a RecyclerView, I'd update the value inside the ArrayList and call mAdapter.notifyDataSetChanged(). So when I scroll, the element has been updated properly.
Related
I'm new to Android Programming.
I want to implement p: data table tag functionality as of prime faces in android.
I want a table layout in XML through which I can iterate over a list of values from bean along with a checkbox for each row.
Using checkbox listener I want that particular row to be editable and vice versa. and that row should contain text views which allow the user to edit the text and also add row functionality which add an empty row to table to allow a user to enter values and save it.
can anyone suggest how can I proceed?
Thank you.
You have to manage all this in your Java class.
Here is a triggerless example for dynamically added checkboxes.
for(int i = 0; i < 20; i++) {
CheckBox cb = new CheckBox(getApplicationContext());
cb.setText("I'm dynamic!");
ll.addView(cb);
}
Here is a simple example. Simply put the event listener on the desired checkbox and do the processing according to what you want.
public class MainActivity extends AppCompatActivity {
private CheckBox checkBox1;
private TextView tv1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView) findViewById(R.id.tv_1);
tv1.setText("This is an example");
checkBox1 = (CheckBox) findViewById(R.id.checkBox1);
checkBox1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(checkBox1.isChecked()){
tv1.setText("Hi i am check");
tv1.setTextColor(Color.RED);
}else {
tv1.setText("Hi i am not checked");
tv1.setTextColor(Color.BLUE);
}
}
});
}
}
So in my application i have a linear layout, to which i'm adding programmatically some CardViews (android L cardview) like this :
//This is my LinearLayout
LinearLayout myLayout = (LinearLayout) findViewById(R.id.accounts_layout);
//Here i create my CardView from a prepared xml layout and inflate it to the LinearLayout
View card = View.inflate(getApplicationContext(), R.layout.account_card, myLayout);
//Now i change the 'text' value of the Card's text views
TextView cardTitle = (TextView) card.findViewById(R.id.text_card_title);
cardTitle.setText("Title1");
TextView cardDecription = (TextView) card.findViewById(R.id.text_card_description);
cardDecription.setText("Description1");
//...
//Now i do the same thing for another card
View card2 = View.inflate(getApplicationContext(), R.layout.account_card, myLayout);
TextView cardTitle2 = (TextView) card2.findViewById(R.id.text_card_title);
cardTitle2.setText("Title2");
TextView cardDecription2 = (TextView) card2.findViewById(R.id.text_card_description);
cardDecription2.setText("Description2");
//...
The two cards are displayed properly, but what happens is than the first card displayed has "Title2" and "Description2" written in the textViews, while the second card has the default values defined in the xml.
It seems to me that by calling card.findViewById() or card2.findViewById() i get always the TextView of the first card.
So my question is : how do i manage to differentiate the cards i create programmatically and then correclty access the view within them?
Try this way,hope this will help you to solve your problem.
LinearLayout myLayout = (LinearLayout) findViewById(R.id.accounts_layout);
for (int i=1;i<=2;i++){
View card = View.inflate(getApplicationContext(), R.layout.account_card, null);
TextView cardTitle = (TextView) card.findViewById(R.id.text_card_title);
cardTitle.setText("Title"+i);
TextView cardDecription = (TextView) card.findViewById(R.id.text_card_description);
cardDecription.setText("Description"+i);
card.setTag(i);
card.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int pos = (Integer) v.getTag();
Toast.makeText(context,pos,Toast.LENGTH_SHORT).show();
}
});
myLayout.addView(card);
}
I have the following issue, I inflate a layout which includes 2 buttons. The onClick method works fine and everything runs smoothly. However I would like to make both buttons that are inflated each time invisible once one of those two is being clicked. I know how to make the button invisbile that was clicked however I find no way of making the corresponding button invisible. Any help is greatly appreciated.
(If it is any concern, this is all done in a fragment)
for(i = 0; i < al.size(); i = i+6) {
TableLayout tl = (TableLayout)fragmentView.findViewById(R.id.myTableLayout);
LayoutInflater inflater1 = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater1.inflate(R.layout.element_request, null);
TextView t1 = (TextView) itemView.findViewById(R.id.tvdescription1);
t1.setText(al.get(i+2));
TextView t2 = (TextView) itemView.findViewById(R.id.tvdescription2);
t2.setText(al.get(i+3));
String id = al.get(i+1);
accept = (Button) itemView.findViewById(R.id.baccept);
accept.setTag(R.id.tvdescription1, id);
String id1 ="a"+id;
accept.setTag(R.id.tvdescription2, id1);
decline = (Button) itemView.findViewById(R.id.bdecline);
decline.setTag(R.id.tvdescription1, id);
String id2 = "b"+id;
decline.setTag(R.id.tvdescription2,id2);
tl.addView(itemView, new TableLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
accept.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
crid = v.getTag(R.id.tvdescription1);
crid2 = crid.toString();
....Code...
accept = (Button)v;
accept.setVisibility(View.GONE);
//----->set corresponding "decline" button also Invisible
}
}
}
You could try this:
ViewGroup row = (ViewGroup) v.getParent();
Button dec = (Button) row.getChildAt(3); //If decline is the 4th member in the view
dec.setVisibility(View.GONE);
There is an really weird thing happening with my listview. I am creating an ListView with buttons and an editText.
It's disposed like this: [Button] [EditText] [Button], The buttons works like an "incrementer" and "decrementer" updating the numerical value of EditText in 1 unit per click.
The problem is, when I click in an button, almost every time an editText of another list view element is changed (the editText of the clicked item is also changed). And if I click in a button of this erroneous changed item, it also changes the editText of the first one. They basically have the same reference of buttons and editText, although they have textViews with data, and this data is different between they.
To accomplish that I created and custom adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = mInflater.inflate(R.layout.lastproduct_row, null);
holder = new ViewHolder();
holder.btnAddQtd = (Button) convertView.findViewById(R.lastproduct_row.btn_add_qtd);
holder.btnSubQtd = (Button) convertView.findViewById(R.lastproduct_row.btn_sub_qtd);
holder.etQuantidade = (EditText) convertView.findViewById(R.lastproduct_row.et_quantidade);
TextView tv;
holder.tvList = new TextView[PRODUCTROW_INT_KEY.length];
for(int i = 0; i < PRODUCTROW_INT_KEY.length; i++) {
tv = (TextView) convertView.findViewById(PRODUCTROW_INT_KEY[i]);
holder.tvList[i] = tv;
}
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
HashMap<String, String> hm = productsList.get(position);
String key = hm.get(CODIGO_KEY);
for(int i = 0; i < PRODUCTROW_INT_KEY.length; i++) {
holder.tvList[i].setText(hm.get(PRODUCTROW_STR_KEY[i]));
}
holder.btnAddQtd.setTag(key+QTD_FLAG+ADD_ACTION);
holder.btnSubQtd.setTag(key+QTD_FLAG+SUB_ACTION);
holder.btnAddQtd.setOnClickListener(handle);
holder.btnSubQtd.setOnClickListener(handle);
if(novosEstoques.containsKey(key)) {
holder.etQuantidade.setText(MyParseFunctions.parseCentesimal(novosEstoques.get(key).getQuantidade()));
}
return convertView;
}
class ViewHolder {
private TextView []tvList;
private Button btnAddQtd, btnSubQtd;
private Button btnAddQtVol, btnSubQtVol;
private EditText etQuantidade, etQtVolume;
}
I added onClick listenners to the buttons, setting their tags with my listView element ID (concatenated with another informations). Then in my event listener I just get the button parent View (an LinearLayout) and get the EditText from that using getViewAt():
#Override
public void onClick(View v) {
String tag = (String) v.getTag();
if(tag.contains(QTD_FLAG)) {
String []info = ((String) v.getTag()).split(QTD_FLAG);
float qtd;
LinearLayout ll = (LinearLayout) v.getParent();
ll.setBackgroundColor(Color.rgb(0, 128, 30));
EditText et = (EditText) ll.getChildAt(2);
qtd = Float.parseFloat(et.getText().toString().replace(",", "."));
if(info[1].equals(ADD_ACTION)) {
qtd++;
}
else if(info[1].equals(SUB_ACTION)) {
if(qtd > 0)
qtd--;
}
Log.d("TESTE", "MODIFICAR KEY = "+info[0]);
et.setText(qtd+"");
}
}
I'm using an setBackgroundColor in this example to confirm that the LinearLayout instance is duplicated in the lisView. When I click an Button, it's painted in 2 different list view item.
Anyone can point me what could be doing this? I have found people with an duplicated ListView item, I don know if that is my case, cause I have TextView's inside my ListView, and they are not equal, only the LinearLayout portion with buttons and editText is "shared".
I make some changes in my getView method and it's working now! It seems that every time the getView method is called i have not guarantee at all that my editTexts will be filled properly and I didn't realize that. So every getView call I make I set the editText value, if the user edit an ET value, I store it in a HashMap to restore in getView, if there is no entry in HashMap for the given editText, then I set it to the default value (zero):
...
if(convertView == null) {
holder = new ViewHolder();
holder.btnAddQtd = (Button) convertView.findViewById(R.lastproduct_row.btn_add_qtd);
holder.btnSubQtd = (Button) convertView.findViewById(R.lastproduct_row.btn_sub_qtd);
holder.etQuantidade = (EditText) convertView.findViewById(R.lastproduct_row.et_quantidade);
//Now it is easier to get etQuantidade reference in button
//click handle, I just have to do:
// public onClick(View v) {
// EditText etButtonAssociated = (EditText) v.getTag();
// ...
// }
holder.btnAddQtd.setTag(holder.etQuantidade);
holder.btnSubQtd.setTag(holder.etQuantidade);
holder.btnAddQtd.setOnClickListener(handle);
holder.btnSubQtd.setOnClickListener(handle);
...
}
else {
...
}
holder.etQuantidade.setTag(key);
if(novosEstoques.containsKey(key)) {
holder.etQuantidade.setText(MyParseFunctions.parseCentesimal(novosEstoques.get(key).getQuantidade()));
}
else {
holder.etQuantidade.setText("0");
}
return convertView;
Israel,
After looking over your code, I was wondering about an implementation decision you have made. Since each Button is "bound" to a particular EditText, have you considered setting the Tag of those Buttons to the EditText? The Tag may be any Object including a UI element. This is especially useful for dynamic UI elements, such as a runtime populated list.
Since this is handled in your Adapter you wouldn't have to worry about duplicate Parents and such. Additionally, you could avoid having to worry about "finding" the control in your onClick() because you would have it (It's the tag). I'm not sure exactly what your project needs are, but this seems like a potentially viable solution, unless you need those Buttons to accomplish other tasks.
Note of Caution
Just make sure that you erase the Tags' references to the EditText when you are done. Otherwise, you run the risk of leaking some memory.
FuzzicalLogic
i want to integrate horizonal scrollview with custom linear layout inflater so i set below code
for (int i=0;i<mArrayListPersonDataLists.size();i++)
{
View child = getLayoutInflater().inflate(R.layout.row_pager_layout, null);
TextView mTextView1=(TextView)child.findViewById(R.id.row_txt_name);
TextView mTextView2=(TextView)child.findViewById(R.id.row_txt_email);
TextView mTextView3=(TextView)child.findViewById(R.id.row_txt_gender);
mLinearLayout.removeAllViews();
mTextView1.setText(mArrayListPersonDataLists.get(i).getName());
mTextView2.setText(mArrayListPersonDataLists.get(i).getEmail());
mTextView3.setText(mArrayListPersonDataLists.get(i).getGender());
mLinearLayout.addView(child);
}
in above my array list include 9 data but in screen it is display only one data so any idea how can i solve this ?
You should write this function like this
mLinearLayout.removeAllViews();
for (int i=0;i<mArrayListPersonDataLists.size();i++)
{
View child = getLayoutInflater().inflate(R.layout.row_pager_layout, null);
TextView mTextView1=(TextView)child.findViewById(R.id.row_txt_name);
TextView mTextView2=(TextView)child.findViewById(R.id.row_txt_email);
TextView mTextView3=(TextView)child.findViewById(R.id.row_txt_gender);
mTextView1.setText(mArrayListPersonDataLists.get(i).getName());
mTextView2.setText(mArrayListPersonDataLists.get(i).getEmail());
mTextView3.setText(mArrayListPersonDataLists.get(i).getGender());
mLinearLayout.addView(child);
}
try this one...
for (int i=0;i<mArrayListPersonDataLists.size();i++)
{
View child = getLayoutInflater().inflate(R.layout.row_pager_layout, null);
TextView mTextView1=(TextView)child.findViewById(R.id.row_txt_name);
TextView mTextView2=(TextView)child.findViewById(R.id.row_txt_email);
TextView mTextView3=(TextView)child.findViewById(R.id.row_txt_gender);
mTextView1.setText(mArrayListPersonDataLists.get(i).getName());
mTextView2.setText(mArrayListPersonDataLists.get(i).getEmail());
mTextView3.setText(mArrayListPersonDataLists.get(i).getGender());
mLinearLayout.addView(child);
child.setId(i+1)
child.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//your code here
int position=child.getId()-1;
Toast.makeText(HorizontalAcivity.this, mArrayListPersonDataLists.get(position).getName(), Toast.LENGTH_SHORT).show();
}
});
}
Remove a line with mLinearLayout.removeAllViews(); :)