Android: Improper layout change due to animation

Asked

Viewed 327 times

2

Guys, I have a problem here and I’ve posted on international stackoverflow, but no one answered me, so I’m posting here to see if you have any charitable soul to help me. Come on!!

I simply wanted to make a list of "tasks" so I used the following layout to list:

lauout/fragment_list.xml:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

<ProgressBar
    android:id="@+id/loading_progress"
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone"
    android:layout_gravity="center" />

<ListView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/listView"
    android:layout_gravity="center_horizontal" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginTop="10dp"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:textStyle="bold"
    android:id="@+id/no_item_message"
    android:visibility="invisible" />

</LinearLayout>

And here are the items that will be inserted in the list:

layout/task.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="horizontal"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:showDividers="middle"
 android:divider="?android:dividerVertical">

<CheckBox
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/task_checkbox"
    android:clickable="true"
    android:enabled="true"
    android:singleLine="false"
    android:gravity="center_horizontal"
    android:layout_marginTop="20dp"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:visibility="visible"/>

<LinearLayout
 android:orientation="vertical"
 android:layout_width="245dp"
 android:layout_height="wrap_content"
 android:layout_marginLeft="10dp"
 android:id="@+id/task_container">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="5dp"
    android:layout_marginRight="10dp"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:hint="@string/title_task"
    android:id="@+id/title_task"
    android:layout_gravity="left|center_vertical" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginRight="10dp"
    android:hint="@string/task_vinculado"
    android:id="@+id/task_vinculado"
    android:layout_gravity="left|center_vertical"
    android:layout_marginTop="5dp" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_marginRight="10dp"
    android:layout_marginBottom="5dp"
    android:hint="@string/limit_date"
    android:id="@+id/limit_date"
    android:layout_gravity="left|center_vertical" />
</LinearLayout>

<ImageButton
    android:id="@+id/delete_task_button"
    android:layout_marginLeft="5dp"
    android:layout_marginTop="15dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_action_discard"
    android:background="?android:selectableItemBackground"
    android:contentDescription="@string/action_remove_item" />

</LinearLayout>

Everything went as I wanted and my layout was like this:

Preview Layout (the colors I configured in the code in Java)

So I decided to do the layout animations described on the Android Developers website (exactly as it is here: Developer.android.com/training/Animation/layout.html)

Then I replaced the/fragment_list.xml layout file with the following file:

layout/test.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

<ScrollView android:layout_width="match_parent"
  android:layout_height="match_parent">

<LinearLayout android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:showDividers="middle"
    android:divider="?android:dividerHorizontal"
    android:animateLayoutChanges="true"
    android:paddingLeft="5dp"
    android:paddingRight="5dp" />

</ScrollView>

<TextView
   android:id="@android:id/empty"
   style="?android:textAppearanceSmall"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_gravity="center"
   android:text="@string/no_task"
   android:padding="32dp"
   android:textColor="?android:textColorSecondary" />

</FrameLayout>

And I’ll manually manipulate the List into a fragment this way:

Taskfragment.java: (code is simplified for better understanding)

public class TaskFragment extends Fragment {
  private ViewGroup mContainerView;
  private View view;


  public TaskFragment() {
  }

  @Override
  public View onCreateView(final LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {

    view = inflater.inflate(R.layout.teste, container, false);
    assert view != null;

    mContainerView = (ViewGroup) view.findViewById(R.id.container);

    return view;
  }


  @Override
  public void onStart(){
     super.onStart();

    ContentResolver contentResolver = getActivity().getContentResolver();
    Uri uri = NectarContract.Task.CONTENT_URI;
    Cursor c = contentResolver.query(uri, NectarContract.Task.PROJECTION, null, null, null);
    assert c != null;
    while (c.moveToNext()) {
        Task task = new Task();
        task.setId(c.getInt(NectarContract.COLUMN_TASK_ID));
        task.setTitle(c.getString(NectarContract.COLUMN_TASK_TITLE));
        task.setVinculado(c.getString(NectarContract.COLUMN_TASK_VINCULADO));
        task.setEnd(c.getString(NectarContract.COLUMN_TASK_END));
        task.setPrioridade(c.getInt(NectarContract.COLUMN_TASK_PRIORIDADE));

        view.findViewById(android.R.id.empty).setVisibility(View.GONE);
        populate(task);
     }
  }

  private void populate(final Task task){
    final ViewGroup newView = (ViewGroup) LayoutInflater.from(getActivity().getApplicationContext()).inflate(R.layout.task, mContainerView, false);

    CheckBox checkbox = (CheckBox) newView.findViewById(R.id.task_checkbox);
    checkbox.setTag(task.getId());
    TextView title = (TextView) newView.findViewById(R.id.title_task);
    TextView vinculado = (TextView) newView.findViewById(R.id.task_vinculado);
    TextView end = (TextView) newView.findViewById(R.id.limit_date);
    LinearLayout container = (LinearLayout) newView.findViewById(R.id.task_container);

    title.setText(task.getTitle());
    if (task.getPrioridade() == 0) {
        title.setTextColor(Color.BLUE);
    }
    if (task.getPrioridade() == 1) {
        title.setTextColor(0xFFE29400);
    }
    if (task.getPrioridade() == 2) {
        title.setTextColor(Color.RED);
    }
    vinculado.setText("Vinculado a: " + task.getVinculado());
    end.setText("Data prevista: " + task.getEndString());

    container.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(getActivity().getApplicationContext(), TaskActivity.class);
            intent.putExtra(ARG_TASK, task);
            intent.putExtra(TaskActivity.USER, user);
            intent.putExtra(TaskActivity.METHOD, TaskActivity.UPDATE);
            startActivityForResult(intent, 1);
        }
    });
    newView.findViewById(R.id.delete_task_button).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mContainerView.removeView(newView);
            if (mContainerView.getChildCount() == 0) {
                view.findViewById(android.R.id.empty).setVisibility(View.VISIBLE);
            }
        }
    });
    mContainerView.addView(newView, 0);
  }
}

But using a list like this, it changed the settings of my layout. Look at this:

Layout Preview 2

I’ve done everything I can to change that, to go back to the old look, and I couldn’t do it at all. What I want is to continue with this layout that supports animation, but with the old look.

Note: all the changes I make in layout/task.xml, it is not right as shown in the preview of Android Studio, I have to go running the application and testing until I stay in the configuration I want, and still there are things I can not change! Will this be an animation API problem?

Thanks in advance for anyone who tries to help me in this!!

  • The problem is in the checkbox, text color and padding right? You know that "no" is recommended to have a Listview inside a Scrollview. I don’t quite understand the motivation to change from fragment_list.xml for teste.xml? Was it just a test? Besides, could you try to detail the problem better? There is a lot of code and it was not clear the problem for me...

  • Exactly, checkbox problem. But I’m not using Listview inside Scrollview, it’s a Linearlayout inside Scrollview. In fact I replaced fragment_list.xml by the test.xml exactly pq it replaces a Listview with Linearlayout within Scrollview, then I manipulate the items within Linearlayout by a Viewgroup object there in the code of my fragment, with the add and remove operation it automatically performs an animation as shown in this link: http://developer.android.com/training/animation/layout.html The problem is that this is giving way to the checkbox.

  • Ah... I get it, you’re not wearing one anymore Adapter to represent your model in ListView and yes doing all this manually... For me it does not make sense this change of "theme". Could you include code that inflates the layout and populates the data? Also, you have tried using the attribute android:animateLayoutChanges="true" in the ListView?

  • Check out what is commented in the code of the sample app of the Android Developers site: "A vertical Linearlayout in a Scrollview. This emulates a Listview (and is Lighter Weight than a Listview when there aren’t Many Rows). Note that this Linearlayout has the "animateLayoutChanges" Property set to true. This Tells the framework to Automatically Animate Child views (in this case, Rows) as they are Added to and Removed from the Linearlayout."

  • Man, I already appreciate your help. Thanks for your attention bro. I don’t android:animateLayoutChanges="true" no Listview pq como uso Adapter, I ended up not being able to manipulate item by item in Listview. What I do in these cases is repopulate my Listview.

  • ready, I edited the post and posted the code that I manipulate the list manually inside Linearlayout. Look if it got better to understand?

  • Okay, I’ll take a look.

  • Thanks bro. Thank you so much!

  • One thing I found strange is to use the getActivity().getApplicationContext() in the final ViewGroup newView = (ViewGroup) LayoutInflater.from(getActivity().getApplicationContext()).inflate(R.layout.task, mContainerView, false);&#xA;. Test one thing: I created a local variable to store the LayoutInflater, initialize it in the onCreateView using only the context of Activity (maybe, I’m not sure, but using the context of the application, you’re missing the theme of your Activity) and reuse this LayoutInflater in the method populate. Ah, pass the container as null in the method inflate.

  • Thanks so much. You solved my problem here. LayoutInflater in onCreateView, actually I just replaced the line final ViewGroup newView = (ViewGroup) LayoutInflater.from(getActivity().getApplicationContext()).inflate(R.layout.task‌​, mContainerView, false); for final ViewGroup newView = (ViewGroup) getActivity().getLayoutInflater().inflate(R.layout.task, mContainerView, false); Vc is the guy, thanks. How can I give you "points" here on the forum? I’m still new to this! hauahauahua

  • I’ll put that recommendation in Context which is passed in the LayoutInflater as an answer to accept. You’re welcome, that’s what we’re here for :)

Show 6 more comments

1 answer

2


Change the Context passed to the LayoutInflater, passing the Application because there is probably a loss of information regarding the theme of Activity.

You can use:

LayoutInflater.from(getActivity());
// ou
getActivity().getLayoutInflater() // Sugerido nos comentários
// ou
(LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  • Exactly that! Thank you very much Walkim!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.