Can move child in LinearLayout up but not down - android

Can someone please explain why the first piece of code here works but not the last piece? The only difference is the index of which i insert my view, i-1 and i+1. Is i+1 just not possible with index? I can write any other number in there and it works.
upButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0; i < drawerViewGroup3.getChildCount(); i++) {
View view = drawerViewGroup3.getChildAt(i);
TextView tv = (TextView) view.findViewById(R.id.drawer_name);
if (tv.getText().toString().equals(drawerName.getText().toString()) && i != 0) {
drawerViewGroup3.removeView(view);
drawerViewGroup3.addView(view, i - 1);
}
}
}
});
downButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0; i < drawerViewGroup3.getChildCount(); i++) {
View view = drawerViewGroup3.getChildAt(i);
TextView tv = (TextView) view.findViewById(R.id.drawer_name);
if (tv.getText().toString().equals(drawerName.getText().toString())) {
drawerViewGroup3.removeView(view);
drawerViewGroup3.addView(view, i + 1);
}
}
}
});
Some context on the app. I have a vertical oriented LinearLayout with multiple LinearLayouts inside. When clicking the two Buttons in the code, one of the children is to move up or down, switching their positions.
EDIT: Ok so I figured it out.
downButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View viewToMove = null;
int viewToMovePos = drawerViewGroup3.getChildCount();
for (int i = 0; i < drawerViewGroup3.getChildCount(); i++) {
View view = drawerViewGroup3.getChildAt(i);
TextView tv = (TextView) view.findViewById(R.id.drawer_name);
if (tv.getText().toString().equals(drawerName.getText().toString()) && i != drawerViewGroup3.getChildCount() - 1) {
viewToMovePos = i;
viewToMove = view;
}
}
alert.dismiss();
if (viewToMovePos != drawerViewGroup3.getChildCount()) {
drawerViewGroup3.removeView(viewToMove);
drawerViewGroup3.addView(viewToMove, viewToMovePos + 1);
}
}
});
Not the prettiest code and probably not gonna help others as it's very specific, but that was the answer.

When you remove a view from your LinearLayout, the view at index i is now the view which was after the one which you removed. Then you add a view at i - 1 which is before this view (the one which was previously after the removed view). The final result is that you remove a view and insert back where it used to be.
Instead, you need to add the view at i - 2.
I suggest that you look at RecyclerView. It is specifically designed to efficiently create a dynamic list of views for given data. You only have to manipulate the data and RecyclerView does all the hard work for you.

Related

Expand all list items in custom ListView (android)

I am using a normal ListView (mItemsList) with expandable animation (from this tutorial). It works, when I click on list item it expands and shows details for this item.
mItemsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
View details = view.findViewById(R.id.details);
// Creating the expand animation for the item
ExpandAnimation expandAni = new ExpandAnimation(details, 500);
// Start the animation on the toolbar
details.startAnimation(expandAni);
}
});
I created a showDetails button and I want to expand all list items after clicking the button, but I am completely lost. Code below doesn't work
mShowDetailsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0; i < mItemsList.getAdapter().getCount(); i++) {
View details= v.findViewById(R.id.details);
details.startAnimation(new ExpandAnimation(details, 500));
}
}
});
Could you help me?
Here's my list_item xml file
Maybe do the similar approach like the following to automatically click item one by one to open all listciew.
mShowDetailsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0; i < mItemsList.getAdapter().getCount(); i++) {
listView.performItemClick(
getViewByPosition(i),
i,
listView.getAdapter().getItemId(i));
}
}
});
//the listview getChildAt only return the view(item) that is visible,
//therefore add a function to get invisible view together
public View getViewByPosition(int position) {
int firstItemPosition = listView.getFirstVisiblePosition();
int lastItemPosition = firstItemPosition + listView.getChildCount() - 1;
if (position < firstItemPosition || position > lastItemPosition ) {//is invisible
return listView.getAdapter().getView(position, null, listView);
} else {
int childIndex = position - firstItemPosition;//is visible
return listView.getChildAt(childIndex);
}
}
The one you do is not work as the view is refering the mShowDetailsButton ,but not mItemsList. Thus, you cannot findViewof id R.id.details.
mShowDetailsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {//<-- this view not referring to mItemsList
}
});

Adding Array of customized View in android and setting onClickListener mutually exclusive

I am adding a Customized View using an array.The array elements are intialized by inflating a layout and adding those elements to a ViewGroup as shown in the image.
When I am setting onClickListener in a way to make the clicked view's background as Accent Color It happens but in order to make it mutually exclusive so that once a view is clicked other View's background should become transparent as they were intially I have used the following code But my when I click on the View, my applications stops responding.If my approach is not correct Please suggest me the right way to get desired result.
This should happen:
this should not happen:
if(noOfChild>1) {
for (j = 0; j < noOfChild; j++) {
LayoutInflater inflater = (LayoutInflater) getSystemService(getApplicationContext().LAYOUT_INFLATER_SERVICE);
childButton[j] = (inflater.inflate(R.layout.child_selection_button, null));
childButton[j].setId(j);
children.addView(childButton[j], new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f));
childButton[j].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.setBackgroundColor(ContextCompat.getColor(MainScreen.this, R.color.dimAccent));
// for (int k =0;k<noOfChild;k++){
// while(k!=v.getId()){
// childButton[k].setBackgroundColor(ContextCompat.getColor(MainScreen.this, R.color.transparent));
// }
// }
}
});
}
}
You can keep a local variable which shows the position of the last selected item. Then in your onClick() method do the switch in the position and the backgroundColor:
private View lastSelected;
//... rest of code ...
//Inside for loop
public void onClick(View v){
if (lastSelected == null){
lastSelected = v;
selectItem(lastSelected);
}
else
{
deselectItem(lastSelected);
lastSelected = v;
selectItem(lastSelected);
}
}
private void selectItem(View v){
v.setBackgroundColor(ContextCompat.getColor(MainScreen.this,R.color.dimAcent));
}
private void deselectItem(View v){
v.setBackgroundColor(ContextCompat.getColor(MainScreen.this, R.color.transparent));
}

UI doesn't get updated sometimes in Android

I am trying to populate data in UI fetched through REST service. The data comes up everytime but the UI doesn't get populated sometimes. The UI is kind of listing but listview is not being used. There's a ScrollView which has LinearLayout as its child and then row views are added to the linearlayout. There are times when UI just doesn't get updated even if the data is passed to it.
private void showData(List list) {
if(list != null && list.isEmpty()) {
mNoData.setVisibility(View.VISIBLE);
} else {
mNoData.setVisibility(View.GONE);
final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.details_layout);
findViewById(R.id.details_progress).setVisibility(View.GONE);
linearLayout.removeAllViews();
LayoutInflater layoutInflater = getLayoutInflater();
View rowView = null;
TextView txtName = null;
Button buttonPlay = null;
for (int i = 0; i < list.size(); i++) {
rowView = layoutInflater.inflate(R.layout.row_view, null);
txtName = (TextView) rowView.findViewById(R.id.row_view_name);
buttonPlay = (Button) rowView.findViewById(R.id.row_view_button_play);
final Item item = (Item) list.get(i);
rowView.setTag(i) ;
txtName.setText(item.getName());
final RecentItem recentItem = RecentsManager.getInstance().getRecentItemFromRefID(item.getId());
if (recentItem !=null) {
buttonPlay.setText(getString("Resume"));
buttonPlay.requestFocus();
}
buttonPlay.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (recentItem!=null) {
//do some action
} else {
//do some action
}
finish();
}
});
final int tag = (Integer) rowView.getTag() ;
rowView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//do some action
}
}) ;
txtName.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//do some action
}
});
buttonPlay.setId(i);
if(i < list.size())
buttonPlay.setNextFocusDownId(i+1);
linearLayout.addView(rowView);
if (i == 0) {
buttonPlay.requestFocus();
buttonPlay.setNextFocusUpId(mButtonReminder.getId());
if(mButtonReminder != null) {
mButtonReminder.setNextFocusDownId(buttonPlay.getId());
}
} else {
buttonPlay.setNextFocusUpId(i-1);
}
}
}
}
I have even checked the linearlayout children's count and the count is always equal to list size which means rows are also being added to it but it just doesn't show up on the UI.
What can be the issue?
you are using condition
if(list != null && list.isEmpty()) {
mNoData.setVisibility(View.VISIBLE);
}
change it to
if(list == null || list.isEmpty()) {
mNoData.setVisibility(View.VISIBLE);
}
I was able to resolve the issue by doing certain changes as adding fillViewPort="true" for scrollview. Also, there was a background thread which was trying to update the UI because of which UI thread was breaking. This didn't resulted in a crash but the UI updation didn't happened. With these two changes it's working fine.

How can I fold all ChildView Group in Android ExpandableList Item?

How can I fold all ChildView Group in Expandable List. Now I have two buttons to control Expand All and Fold All on Activity. Expandable button is OK and it is working work but I don't know how to fold all ChildView Group. How can i do this ?
Thanks
**expandableListView.expandGroup(position, true); = OK<Br>
expandableListView.foldGroup(position) = ? or ?**
try this,
int count = (new ExpAdapter(this)).getGroupCount();
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0; i < count; i++)
{
expList.collapseGroup(i);
}
}
});

How to get a count of list items from Listview?

I'm using below code to travers my list it is working fine if List Items are visible.
If List is scrollable then non visible items are not accessing using this code. How to traverse all the list items which are visble + non visible items.
for(int i=0;i<list.getCount;i++)
{
View v = list.getChildAt(i);
TextView tv= (TextView) v.findViewById(R.id.item);
Log.d("","ListItem :"+tv.getText());
}
Here is how you can get your ListView in the Activity and traverse it.
ListView myList = getListView();
int count = myList.getCount();
for (int i = 0; i < count; i++)
{
ViewGroup row = (ViewGroup) myList.getChildAt(i);
TextView tvTest = (TextView) row.findviewbyid(R.id.tvTestID);
// Get your controls from this ViewGroup and perform your task on them =)
}
I hope this will help
Recently i did this thing.
Suppose i want to invisible a button on a listItem. Then in the getView of the list adapter add that button in a global vector. like below.
Button del_btn = viewCache.getFrame();
view_vec.add(del_btn);
Here viewCache is a object of ViewCache class, which is sumthing like below -
class ViewCache
{
private View baseView;
private Button button;
public ViewCache(View baseView)
{
this.baseView = baseView;
}
public Button getButton() {
if(button == null) {
button = (Button) baseView.findViewById(R.id.DeleteChatFrndBtn);
}
return button;
}
}
//it is necessary sometimes because otherwise in some cases the list scroll is slow.
Now you like to visible the listItem's button onClicking some other button. Then the code is like below -
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()) {
case R.id.EditChatFrndBtn:
length = view_vec.size();
for(int i = 0; i < length; i++) {
Button btn = (Button) view_vec.elementAt(i);
btn.setVisibility(View.VISIBLE);
}
doneBtn.setVisibility(View.VISIBLE);
editBtn.setVisibility(View.INVISIBLE);
break;
}
}
Instead of R.id.EditChatFrndBtn put your button id on clicking of which you will invisible/visible the listItem's button.

Categories

Resources