#android
Как сделать растягивание изображения как в Viber'e? Когда зажимаешь картинку контакта и тянешь вниз и она расширяется, а отпустишь палец размер картинки станет нормальным.
Ответы
Ответ 1
Выдался мне свободный денек и решил реализовать я предложенную задачу. Сразу небольшой демонстрационный проект на GitHub, картинка (прошу прощения за розовую херню, такая программа захвата попалась) и ниже немного пояснений. Реализовать подобный эффект можно несколькими способами, я решил выбрать самый простой - расширение FrameLayout, который, как известно позволяет наложить элементы друг на друга, смещение двух элементов и управление движением через onTouchEvent(), плюс еще замечательная анимация возврата при отпускании. Собственно сам класс расширяющий FrameLayout: // имя пакета, потребуется в разметке, у вас будет какое-то свое package com.example.stretchview; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; public class StretchLayout extends FrameLayout { final float DEFAULT_RATIO = 0.5F; float mTouchY; float mTranslateY; float mMargin; float mRatio; View mStretchView; View mFrontView ; public StretchLayout(Context context) { super(context); init(); } public StretchLayout(Context context, AttributeSet attrs) { super(context, attrs); init(); } public StretchLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mRatio = DEFAULT_RATIO; } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: mTouchY = event.getY(); break; case MotionEvent.ACTION_MOVE: mTranslateY = event.getY() - mTouchY; if (mTranslateY >= mMargin) mTranslateY = mMargin; if (mTranslateY <0) mTranslateY = 0; mFrontView.setTranslationY(mTranslateY); mStretchView.setTranslationY(mTranslateY/2); break; case MotionEvent.ACTION_UP: mTranslateY = 0; mFrontView.animate().translationY(mTranslateY).setInterpolator(new DecelerateInterpolator()); mStretchView.animate().translationY(mTranslateY).setInterpolator(new DecelerateInterpolator()); break; } return true; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); mStretchView = getChildAt(0); mFrontView = getChildAt(1); mMargin = mStretchView.getMeasuredHeight()*mRatio; mFrontView.setTop((int)(mMargin)); mStretchView.setTop((int) (-mMargin/2)); } protected void setRatio (float ratio){ mRatio = ratio; } } Теперь - как этим пользоваться. Создаем разметку (activity_main.xml), которая обязательно должна включать два элемента, названные мной stretch_view- тот, что частично скрывается и front_view - который его закрывает - вы можете использовать свои идентификаторы. Второй элемент у меня LinearLayout, который содержит пару кнопок для примера. Параметр android:adjustViewBounds="true" указывает,чтобы изображение занимало только необходимое ему по размерам место. Так же прошу обратить внимание на то, как указан наш кастомный лэйаут - с полным именем, включающим название пакета этого лэйаута.Активити, в которой все это вызывается не блещет оригинальностью: public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } Если дефолтный коэффициент перекрытия (половина высоты изображения) не устраивает - его можно изменить методом setRatio(float ratio), ratio может принимать значения от 0 до 1 ( картинку полностью не видно - картинка полностью раскрыта) Конечно здесь есть еще,что улучшить, к примеру парсинг этого ratio из xml-аттрибутов разметки, дополнительные проверки от падения и тп. Может где то я совершил по незнанию что то страшное, прошу строго не судить, а ткнуть носом .. все это на самом деле замечательно работает. Минимальный API - 14, для 2.* андроид много костылей надо
Комментариев нет:
Отправить комментарий