Андроид - Как смотреть с экрана?



Я пытаюсь анимировать простой ImageView в моем приложении, и я хочу, чтобы он скользил в нижней части экрана и пришел в положение покоя, где верхний 50px представления находится в верхней части экрана (например, конечное положение ImageView должно быть-50px в X). Я попытался использовать AbsoluteLayout для этого, но это на самом деле отрезает верхнюю 50px ImageView таким образом, что верхняя 50px никогда не отображается. Мне нужно, чтобы верхний 50px ImageView был виден/визуализирован, пока это анимация, а затем просто он пришел в состояние покоя немного за кадром. Надеюсь, я объяснил это достаточно хорошо.



вот что я в настоящее время использую в качестве макета и слайд-в анимации (это в настоящее время не отображает топ 50px ImageView):



планировка:



<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:id="@+id/QuickPlayClipLayout">
<ImageView android:id="@+id/Clip"
android:background="@drawable/clip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_y="-50dp">
</ImageView>
</AbsoluteLayout>


анимация:



<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="100%p"
android:toYDelta="0"
android:duration="1000"/>
<alpha android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="1000" />
</set>


спасибо заранее.

549   6  

6 ответов:

Я придумал решение для этого, которое должно быть легко реализовать. Он включает в себя изменение макета и деятельность, раздувающую макет... смотрите ниже:

Активность (QuickPlay.java):

public class QuickPlay extends Activity implements AnimationListener
{
    private ImageView myImageView;
    private LinearLayout LL;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.quick_play_screen);

        myImageView = (ImageView) this.findViewById(R.id.Clip);
        LL = (LinearLayout) this.findViewById(R.id.QuickPlayClipLayout);

        //finally
        Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_in_quickplay);
        anim.setAnimationListener(this);
        LL.startAnimation(anim);
    }
    @Override
    public void onAnimationEnd(Animation animation){}

    @Override
    public void onAnimationRepeat(Animation animation){}

    @Override
    public void onAnimationStart(Animation animation)
    {
        // This is the key...
        //set the coordinates for the bounds (left, top, right, bottom) based on the offset value (50px) in a resource XML
        LL.layout(0, -(int)this.getResources().getDimension(R.dimen.quickplay_offset), 
                LL.getWidth(), LL.getHeight() + (int)this.getResources().getDimension(R.dimen.quickplay_offset));
    }
}

New LinearLayout (CustomLinearLayout.java):

public class CustomLinearLayout extends LinearLayout
{
    private Context myContext;

    public CustomLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        myContext = context;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec+((int)myContext.getResources().getDimension(R.dimen.quickplay_offset)));
    }
}

Layout (/res/layout/quick_play_screen.xml):

<?xml version="1.0" encoding="utf-8"?>
   <com.games.mygame.CustomLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_height="fill_parent" 
      android:layout_width="fill_parent" 
      android:id="@+id/QuickPlayClipLayout">
      <ImageView android:id="@+id/Clip"
         android:background="@drawable/clip" 
         android:layout_width="fill_parent" 
         android:layout_height="wrap_content">
      </ImageView>
   </com.games.mygame.CustomLinearLayout>

Resource (/res/values/constants.xml):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="quickplay_offset">50dp</dimen>
</resources>

анимация (/res/anim / slide_in_quickplay.xml):

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
   <translate android:fromYDelta="100%p" 
       android:toYDelta="0"
       android:duration="1000"/>
   <alpha android:fromAlpha="0.0" 
       android:toAlpha="1.0"
       android:duration="1000" />
</set>

программа теперь делает именно то, что мне нужно. Весь макет начинается с экрана внизу, скользит в 1 сек и приходит в состояние покоя, где верхняя часть макета на самом деле 50px от верхней части экрана (т. е. LL.getTop() = -50) и нижняя часть макета находится в нижней части экрана (т. е. LL.getBottom() = 530 = 480 + 50).

для размещения моего вида за кадром я использовал следующий код:

View myView = /* view you want to position offscreen */
int amountOffscreen = (int)(myView.getWidth() * 0.8); /* or whatever */
boolean offscreen = /* true or false */


int xOffset = (offscreen) ? amountOffscreen : 0;
RelativeLayout.LayoutParams rlParams = 
    (RelativeLayout.LayoutParams)myView.getLayoutParams();
rlParams.setMargins(-1*xOffset, 0, xOffset, 0);
myView.setLayoutParams(rlParams);

этот код будет позиционировать myView offscreen по amountOffscreen, который в этом случае помещает 80% экрана просмотра, оставляя только 20% на экране.

Не используйте метод layout() напрямую - Android будет делать последующие вызовы для аннулирования вашего представления по случайным причинам, и только layoutParams сохраняются при недействительных вызовах. Если вам интересно, проверьте линии 904 до 912 из этого файл чтобы понять, почему вы должны изменить layoutParams.

вместо этого мы можем просто дать отрицательные значения layout_margin(Top / left / right / bottom) например: если вы хотите, чтобы ваш вид был выключен из верхней части экрана, вы можете указать

android:layout_marginTop="-40dp"

это легко сделать, если вы сделаете прыжок с помощью Canvas; те поддерживают рисование с экрана без каких-либо проблем. Однако реализовать его будет сложнее. Вам нужно будет реализовать пользовательский View и написать свою собственную анимацию в коде. По сути, это сводится к простой обработке 2D-графики, а не к просмотру с использованием встроенных анимаций XML. Возможно, есть способ сделать это с помощью XML, но я гораздо больше знаком с холстами. Очень хорошее место, чтобы увидеть, как это происходит в код-это пример игры Lunar Lander, который поставляется с SDK.

примерно шаги, которые вы должны следовать, являются:

  1. поместите пользовательский вид в XML-файл, используя что-то вроде <your.package.AnimatingView>, установив его размер, чтобы заполнить родителя.

  2. затем определите класс AnimatingView, который extends SurfaceView and implements SurfaceHolder.Callback. (Это дает вам доступ к чертежу Canvas сразу, а не с помощью invalidate() метод. Это важно, потому что invalidate () только обновляется, когда поток простаивает, например, в конце цикла. Чтобы реализовать анимацию, вы должны иметь его рисунок сразу.)

  3. затем вы можете реализовать цикл, который рисует ваше перемещение изображения по экрану. Цикл должен начинаться с рисования всего фона (потому что холст автоматически не стирается), а затем нарисовать изображение в его новом положении на основе прошедшего времени. Например, если вы хотите, чтобы ваша анимация займет 1 секунду сделайте, тогда вы знаете, что если прошло 200 мс, вид должен был переместиться только на 200/1000 или 1/5 пути от своего начального положения до конечного положения.

вы можете увидеть некоторые примеры того, что я имею в виду в моих других ответах на вопросы анимации: основной ответ о полезность использования SurfaceView и пример цикла для использования. Примечание: второй вопрос был о вращении, и, следовательно, некоторые из трудностей, о которых я говорил это не будет иметь к вам никакого отношения. Удачи вам!

У меня была группа просмотра с детьми и перетаскивала вид на экран снизу - вроде как ящик. Затем я отпустил бы, и если бы верхний край viewgroup был в верхней половине экрана, я бы анимировал его сверху после того, как пользователь отпустил прикосновение.

когда это произошло, изображения в дочерних элементах viewgroup будут обрезаны во время анимации, но затем будут показаны после анимации.

проблема: высота viewgroup была wrap_content в качестве параметров. Я решил эту проблему, установив высоту на значение, которое растянулось с экрана до начала анимации.

С android:translationX и android:translationY

<RelativeLayout
        android:translationX="-600dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent">

Comments

    Ничего не найдено.