জিমেইল থ্রি-ফ্যাগমেন্ট অ্যানিমেশন সিনারিওর সম্পূর্ণ কাজের নমুনা?


128

টিএল; ডিআর: আমি "জিমেইল থ্রি-ফ্র্যাগমেন্ট অ্যানিমেশন" দৃশ্যের হিসাবে যা উল্লেখ করব তার একটি সম্পূর্ণ কাজের নমুনা খুঁজছি । বিশেষত, আমরা দুটি টুকরা দিয়ে এর সাথে শুরু করতে চাই:

দুটি টুকরা

কিছু ইউআই ইভেন্টের (উদাহরণস্বরূপ, খণ্ড বি-তে কোনও কিছুতে ট্যাপ করা), আমরা চাই:

  • বাম দিকে স্ক্রিনটি স্লাইড করতে ফ্র্যাগমেন্ট এ
  • টুকরা বি স্ক্রিনের বাম প্রান্তে স্লাইড করতে এবং ফ্রেগমেন্ট এ দ্বারা খালি স্থানটি সরিয়ে নিতে সঙ্কুচিত হবে
  • স্ক্রিনের ডান দিক থেকে স্লাইড করতে এবং ফ্রেগমেন্ট বি দ্বারা খালি করা স্থানটি নিতে ফ্রেগমেন্ট সি

এবং একটি ব্যাক বোতাম টিপে, আমরা চাই যে ক্রিয়াকলাপগুলির সেটটি উল্টানো হোক।

এখন, আমি প্রচুর আংশিক বাস্তবায়ন দেখেছি; আমি নীচে তাদের চারটি পর্যালোচনা করব। অসম্পূর্ণ হওয়ার বাইরেও তাদের সবার সমস্যা রয়েছে।


@ রিটো মেয়ার একই জনপ্রিয় প্রশ্নের এই জনপ্রিয় উত্তরটির অবদান রেখেছেন , এটি ইঙ্গিত করে যে আপনি কোনটি setCustomAnimations()দিয়ে ব্যবহার করবেন FragmentTransaction। দ্বি-খণ্ডের দৃশ্যের জন্য (উদাহরণস্বরূপ, আপনি কেবল প্রাথমিকভাবে খণ্ড A এ দেখেন এবং এনিমেটেড এফেক্টস ব্যবহার করে এটি একটি নতুন টুকরা বি দিয়ে প্রতিস্থাপন করতে চান), আমি সম্পূর্ণ চুক্তিতে আছি। যাহোক:

  • যেহেতু আপনি কেবলমাত্র একটি "ইন" এবং একটি "আউট" অ্যানিমেশন নির্দিষ্ট করতে পারেন, তাই ত্রি-খণ্ডের দৃশ্যের জন্য প্রয়োজনীয় সমস্ত ভিন্ন অ্যানিমেশন আপনি কীভাবে পরিচালনা করবেন তা আমি দেখতে পাচ্ছি না
  • <objectAnimator>তার নমুনা কোডে পিক্সেলে হার্ড-ওয়্যার্ড অবস্থানের ব্যবহার করে এবং স্ক্রীনে মাপ নানারকম দেওয়া অকার্যকর হবে বলে মনে হচ্ছে না, এখনো setCustomAnimations()প্রয়োজন অ্যানিমেশন সম্পদ, জাভা এসব সংজ্ঞা সম্ভাবনা precluding
  • আমি যেমন লোকসানে চাইছি সবকিছু কীভাবে দিয়ে স্কেল টাই জন্য বস্তু অ্যানিমেটরবৃন্দ পছন্দ android:layout_weightএকটি LinearLayoutশতকরা ভিত্তিতে স্থান বণ্টন জন্য
  • আমি অসম্পূর্ণ অংশ সি গোড়াতেই পরিচালিত হয় হিসেবে লোকসানে কোথায় ( GONE? android:layout_weightএর 0? 0? অন্য কিছু স্কেলে প্রাক-অ্যানিমেটেড?)

@ রোমান নুরিক উল্লেখ করেছেন যে আপনি নিজের দ্বারা সংজ্ঞায়িত সম্পত্তি সহ আপনি যে কোনও সম্পত্তি সঞ্চার করতে পারেন । এটি নিজের কাস্টম লেআউট ম্যানেজার সাবক্লাস আবিষ্কার করে ব্যয় করে শক্ত ওয়্যারযুক্ত অবস্থানগুলির সমস্যা সমাধানে সহায়তা করতে পারে। এটি কিছু সাহায্য করে, কিন্তু আমি এখনও রেটোর বাকী সমাধানগুলি দ্বারা বিস্মিত।


এর লেখক এই পেস্টবিন এন্ট্রিটির কিছু তাত্পর্যপূর্ণ সিউডোকোড দেখায়, মূলত বলেছিল যে তিনটি খণ্ড প্রাথমিকভাবে ধারকটিতে থাকবে, ফ্রেগমেন্ট সি hide()লেনদেনের ক্রিয়াকলাপের মাধ্যমে গোপনে লুকিয়ে থাকবে। ইউআই ইভেন্টটি যখন ঘটে তখন আমরা তখন show()সি এবং hide()এ। যাইহোক, আমি দেখতে পাচ্ছি না যে এটি কীভাবে বি আকার পরিবর্তন করে hand এটি এও নির্ভর করে যে আপনি দৃশ্যত একই পাত্রে একাধিক টুকরো যোগ করতে পারেন, এবং দীর্ঘমেয়াদে এটি নির্ভরযোগ্য আচরণ কিনা তা আমি নিশ্চিত নই (এটি ভেঙে যাওয়া উচিত উল্লেখ করা উচিত findFragmentById(), যদিও আমি তার সাথে বেঁচে থাকতে পারি)।


এই ব্লগ পোস্টটির লেখক ইঙ্গিত দেয় যে জিমেইল মোটেও ব্যবহার setCustomAnimations()করছে না, বরং সরাসরি অবজেক্ট অ্যানিমেটারগুলি ব্যবহার করে ("আপনি কেবলমাত্র মূল ভিউটির বাম মার্জিন + ডান দৃশ্যের প্রস্থ পরিবর্তন করুন") ব্যবহার করেন। যাইহোক, এটি এখনও একটি দ্বি-খণ্ড সমাধান AFAICT, এবং বাস্তবায়ন আবার পিক্সেলের শক্ত তারের মাত্রা দেখানো হয়েছে।


আমি এটি এড়িয়ে চলতে থাকব, তাই আমি নিজেই এই উত্তরটি কোনও দিনই সাড়াতে পারি, তবে আমি সত্যিই আশা করছি যে কেউ এই অ্যানিমেশন দৃশ্যের জন্য তিনটি খণ্ড সমাধান সমাধান করেছেন এবং কোডটি (বা এর কোনও লিঙ্ক) পোস্ট করতে পারেন। অ্যান্ড্রয়েডে অ্যানিমেশনগুলি আমার চুলগুলি টেনে আনতে চায় এবং আপনারা যারা আমাকে দেখেছেন তারা জানেন যে এটি একটি বৃহত ফলদায়ক প্রচেষ্টা।


2
রোমেন গাই পোস্ট করা কি এমন কিছু নয়? কৌতূহলী- creature.org/2011/02/22/…
ফার্নান্দো

1
@ ফেরডি 182: তিনি টুকরো টুকরোটি ব্যবহার করছেন না। দৃশ্যত, এটি সঠিক প্রাথমিক প্রভাব এবং আমি খণ্ড-ভিত্তিক উত্তর তৈরির চেষ্টা করার জন্য এটি অন্য ডেটা পয়েন্ট হিসাবে ব্যবহার করতে সক্ষম হতে পারি। ধন্যবাদ!
কমন্সওয়্যার

1
কেবল একটি চিন্তাভাবনা: স্ট্যান্ডার্ড ইমেল অ্যাপ্লিকেশনটির আমার নেক্সাস 7 এ একই রকম (যদিও সম্পূর্ণ অভিন্ন নয়) আচরণ রয়েছে - যা ওপেন সোর্স হওয়া উচিত।
ক্রিস্টোফার অর

4
ইমেল অ্যাপ্লিকেশনটিতে একটি কাস্টম "থ্রিপেইনলআউট" ব্যবহার করা হয় যা বাম-হাতের অবস্থানের অবস্থান এবং অন্যান্য দুটি দর্শনের প্রস্থ / দৃশ্যমানতা - যেগুলির প্রত্যেকটিতে প্রাসঙ্গিক খণ্ড রয়েছে।
ক্রিস্টোফার অর

2
আরে @ কমন্সওয়্যার, আমি এখানে আমার সম্পূর্ণ উত্তর দিয়ে পিপিএলকে বিরক্ত করব না, তবে আপনার একটি অনুরূপ প্রশ্ন ছিল যা আমি খুব সন্তোষজনক উত্তর দিয়েছি। সুতরাং, শুধু পরামর্শ আপনি এটি চেক করার জন্য (এছাড়াও মন্তব্যগুলি পরীক্ষা): stackoverflow.com/a/14155204/906362
Budius

উত্তর:


67

আমার প্রস্তাবটি গিথুবে আপলোড করেছেন (সব ধরণের অ্যান্ড্রয়েড সংস্করণ নিয়ে কাজ করছে যদিও এই ধরণের অ্যানিমেশনগুলির জন্য হার্ডওয়ার ত্বরণকে দৃ strongly়ভাবে সুপারিশ করা হয় non নন হার্ডওয়ার ত্বরণযুক্ত ডিভাইসগুলির জন্য বিটম্যাপ ক্যাশেিং প্রয়োগ আরও ভাল ফিট করা উচিত)

অ্যানিমেশন সহ ডেমো ভিডিও এখানে (স্ক্রিন কাস্টের ধীর ফ্রেমের হারের কারণ ual প্রকৃত অভিনয় খুব দ্রুত)


ব্যবহার:

layout = new ThreeLayout(this, 3);
layout.setAnimationDuration(1000);
setContentView(layout);
layout.getLeftView();   //<---inflate FragmentA here
layout.getMiddleView(); //<---inflate FragmentB here
layout.getRightView();  //<---inflate FragmentC here

//Left Animation set
layout.startLeftAnimation();

//Right Animation set
layout.startRightAnimation();

//You can even set interpolators

ব্যাখ্যা :

একটি নতুন প্রথা তৈরি করেছে রিলেটিভলআউট (থ্রিলআউট) এবং 2 টি কাস্টম অ্যানিমেশন তৈরি করেছে (মাইস্কালএ্যানিমেশন, মাই ট্রান্সলেটএনিমেশন)

ThreeLayoutবাম ফলকের ওজনকে পরম হিসাবে পাওয়া যায়, ধরে নেওয়া যায় যে অন্যান্য দৃশ্যমান মতামত রয়েছে weight=1

সুতরাং new ThreeLayout(context,3) 3 শিশু এবং মোট পর্দার 1/3 অংশ সহ বাম ফলকে একটি নতুন দর্শন তৈরি করে। অন্যান্য দৃশ্য সমস্ত উপলব্ধ স্থান দখল করে।

এটি রানটাইমে প্রস্থকে গণনা করে, একটি নিরাপদ বাস্তবায়ন হ'ল মাত্রাগুলি প্রথমবার অঙ্কন () এ গণনা করা হয়। পোস্টের পরিবর্তে ()

স্কেল এবং অনুবাদ অ্যানিমেশনগুলি বাস্তবে আকার পরিবর্তন এবং ভিউ সরান এবং ছদ্ম- [স্কেল, সরানো] নয়। লক্ষ্য করুনfillAfter(true) কোথাও ব্যবহার করা হয় না।

ভিউ 2 দেখুন 1 এর ডান_

এবং

ভিউ 3 হ'ল ভিউ 2-র অধিকার

এই নিয়মগুলি সেট করা রিলেটিভলআউট অন্য সমস্ত কিছুর যত্ন নেয়। অ্যানিমেশনগুলি margins(চলার পথে) এবং ter[width,height] স্কেলগুলিকে

প্রতিটি শিশু অ্যাক্সেস করতে (যাতে আপনি এটি করতে পারেন যাতে আপনার খন্ডের সাথে এটি কল করতে পারেন

public FrameLayout getLeftLayout() {}

public FrameLayout getMiddleLayout() {}

public FrameLayout getRightLayout() {}

নীচে 2 অ্যানিমেশন প্রদর্শিত হয়


ধাপ 1

--- স্ক্রিনে ----------! ----- আউট ----

[View1] [_____ View2 _____] [_____ View3_____]

ধাপ ২

--আউট -! -------- স্ক্রিনে ------

[View1] [View2] [_____ View3_____]


1
যদিও আমি এখনও স্কেল অ্যানিমেটার বাস্তবায়ন করি নি, আমি উদ্বিগ্ন যে এটি রঙের দৃ solid় ক্ষেত্রগুলির জন্য ভাল এবং কম ভাল কাজ করবে, তবে আমরা কি "আসল" সামগ্রী বলব। খণ্ড বি এর স্থান ফিট করতে খণ্ড খের ফলাফল পুনরায় আকার দেওয়া হচ্ছে ফ্রেগমেন্ট বিটি মূলত সেখানে রাখা হয়েছে কিনা তার চেয়ে আলাদা হওয়া উচিত। উদাহরণস্বরূপ, এএফআইএকে, একটি স্কেল অ্যানিমেটার ফন্টের আকারকে মাপবে (অ্যানিমেটেড ছোটতে সমস্ত কিছু আঁকিয়ে View), তবে জিমেইল / ইমেলগুলিতে আমরা ছোট ফন্টগুলি পাই না, কেবল কম শব্দই পাই।
কমন্সওয়্যার

1
@ কমন্সওয়্যার স্কেলএনিমেশন কেবল একটি বিমূর্ত নাম। আসলে কোন স্কেলিং হয় না। এটি আসলে দেখার প্রস্থকে আকার দেয় res উত্স পরীক্ষা করুন। লেআউটরাইজার এটির জন্য আরও ভাল নাম হতে পারে।
দুর্বল

1
এটি scaleXমূল্যের মূল্যের উত্স সম্পর্কে আমার ব্যাখ্যা নয় View, যদিও আমি জিনিসগুলির ভুল ব্যাখ্যা করতে পারি pre
কমন্সওয়্যার

1
@ কমন্সওয়্যার এই github.com/weakwire/3PaneLayout/blob/master/src/com/example/… দেখুন । অ্যানিমেশনটি বাড়ানোর একমাত্র কারণ হ'ল আন্তঃপোল্টেড টাইমে অ্যাক্সেস পাওয়া। p.width = (int) প্রস্থ; সমস্ত যাদু করে এবং এটি স্কেল এক্স নয়। এটি প্রকৃত দেখার মাত্রা যা নির্দিষ্ট সময়কালে পরিবর্তিত হয়।
দুর্বল করুন

2
আপনার ভিডিওটি একটি ভাল ফ্রেমরেট দেখায়, তবে আপনার উদাহরণে ব্যবহৃত মতামতগুলি খুব সহজ। অ্যানিমেশনের সময় একটি অনুরোধ লেআউট () করা খুব ব্যয়বহুল। বিশেষত যদি বাচ্চারা জটিল হয় (উদাহরণস্বরূপ একটি তালিকাভিউ)। এটি সম্ভবত একটি চপি অ্যানিমেশন এর ফলস্বরূপ। GMail অ্যাপ্লিকেশনটি অনুরোধ লেআউটকে কল করে না। পরিবর্তে, অ্যানিমেশন শুরু হওয়ার ঠিক আগে আরেকটি ছোট ভিউ মাঝারি প্যানেলে রাখা হয়।
থিয়েরি-দিমিত্রি রায়

31

ঠিক আছে, প্রশ্নটির মন্তব্যে @ ক্রিস্টোফারের পরামর্শ অনুযায়ী ইমেল এওএসপি অ্যাপ্লিকেশন থেকে প্রাপ্ত আমার নিজস্ব সমাধান এখানে।

https://github.com/commonsguy/cw-omnibus/tree/master/Animation/ThreePane

@ দুর্বলতার সমাধানটি আমার মনে করিয়ে দেয়, যদিও তিনি Animationঅ্যানিমেটারগুলির চেয়ে ক্লাসিক ব্যবহার করেন এবং RelativeLayoutঅবস্থান নির্ধারণের জন্য তিনি নিয়ম ব্যবহার করেন । অনুগ্রহজনক দৃষ্টিকোণ থেকে, তিনি সম্ভবত অনুগ্রহ পাবেন, যদি না চতুর সমাধান সহ অন্য কেউ উত্তর পোস্ট না করে।


সংক্ষেপে, ThreePaneLayoutপ্রকল্পটি একটি LinearLayoutসাবক্লাস, তিনটি বাচ্চাদের সাথে ল্যান্ডস্কেপে কাজ করার জন্য ডিজাইন করা। এই বাচ্চাদের প্রশস্ততা XML লেআউটে সেট করা যেতে পারে, কাঙ্ক্ষিত যে কোনও উপায়ে - আমি ওজন ব্যবহার করে দেখাই, তবে আপনার মাত্রা সংস্থান বা যা কিছু দ্বারা নির্দিষ্ট প্রস্থ নির্ধারণ করা যেতে পারে। তৃতীয় শিশু - প্রশ্নে টুকরা সি - এর শূন্য প্রস্থ থাকা উচিত।

package com.commonsware.android.anim.threepane;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;

public class ThreePaneLayout extends LinearLayout {
  private static final int ANIM_DURATION=500;
  private View left=null;
  private View middle=null;
  private View right=null;
  private int leftWidth=-1;
  private int middleWidthNormal=-1;

  public ThreePaneLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    initSelf();
  }

  void initSelf() {
    setOrientation(HORIZONTAL);
  }

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

    left=getChildAt(0);
    middle=getChildAt(1);
    right=getChildAt(2);
  }

  public View getLeftView() {
    return(left);
  }

  public View getMiddleView() {
    return(middle);
  }

  public View getRightView() {
    return(right);
  }

  public void hideLeft() {
    if (leftWidth == -1) {
      leftWidth=left.getWidth();
      middleWidthNormal=middle.getWidth();
      resetWidget(left, leftWidth);
      resetWidget(middle, middleWidthNormal);
      resetWidget(right, middleWidthNormal);
      requestLayout();
    }

    translateWidgets(-1 * leftWidth, left, middle, right);

    ObjectAnimator.ofInt(this, "middleWidth", middleWidthNormal,
                         leftWidth).setDuration(ANIM_DURATION).start();
  }

  public void showLeft() {
    translateWidgets(leftWidth, left, middle, right);

    ObjectAnimator.ofInt(this, "middleWidth", leftWidth,
                         middleWidthNormal).setDuration(ANIM_DURATION)
                  .start();
  }

  public void setMiddleWidth(int value) {
    middle.getLayoutParams().width=value;
    requestLayout();
  }

  private void translateWidgets(int deltaX, View... views) {
    for (final View v : views) {
      v.setLayerType(View.LAYER_TYPE_HARDWARE, null);

      v.animate().translationXBy(deltaX).setDuration(ANIM_DURATION)
       .setListener(new AnimatorListenerAdapter() {
         @Override
         public void onAnimationEnd(Animator animation) {
           v.setLayerType(View.LAYER_TYPE_NONE, null);
         }
       });
    }
  }

  private void resetWidget(View v, int width) {
    LinearLayout.LayoutParams p=
        (LinearLayout.LayoutParams)v.getLayoutParams();

    p.width=width;
    p.weight=0;
  }
}

যাইহোক, রানটাইমের সময়, আপনি মূলত প্রস্থগুলি কীভাবে সেট আপ করেন তা বিবেচনাধীন নয়, ThreePaneLayoutআপনি প্রথম বারের মাধ্যমে প্রস্থ পরিচালনা hideLeft()এবং বিভাজনকে সি এবং খণ্ড খণ্ডিত খণ্ডিত খণ্ডিত খণ্ডিত খণ্ডিত প্রশ্নগুলির প্রবন্ধটি দেখিয়ে পরিবর্তন করবেন of ThreePaneLayout- যা টুকরা করার কোন নির্দিষ্ট বন্ধন আছে - তিন টুকরা left, middleএবং right। সময় আপনাকে কল এ hideLeft(), আমরা এর মাপ রেকর্ড leftএবং middleএবং কোন ওজন যে, তিন কোনো ব্যবহার করা হয়েছে তাই আমরা সম্পূর্ণরূপে মাপ নিয়ন্ত্রণ করতে পারেন আউট শূন্য। সময় মুহুর্তে hideLeft(), আমরা মাপ নির্ধারণ করে rightমূল আকার হতে middle

অ্যানিমেশনগুলি দ্বিগুণ:

  • একটি ব্যবহার করুন ViewPropertyAnimatorপ্রস্থ দ্বারা বামে তিন উইজেট একটি অনুবাদ সম্পাদন করতে left, একটি হার্ডওয়্যার স্তর ব্যবহার
  • এর প্রস্থের মূল প্রস্থে যা শুরু হয়েছিল তার থেকে প্রস্থ পরিবর্তন করার জন্য ObjectAnimatorএকটি কাস্টম সিউডো-সম্পত্তি ব্যবহার করুনmiddleWidthmiddleleft

(এটি সম্ভব যে এটিগুলির জন্য AnimatorSetএবং ObjectAnimatorsএই সকলের জন্য ব্যবহার করা আরও ভাল ধারণা is

(এটিও সম্ভব যে middleWidth ObjectAnimatorহার্ডওয়্যার স্তরটির মানটিকে অবহেলা করে, যেহেতু এর জন্য মোটামুটি অবিচ্ছিন্ন অবৈধতা প্রয়োজন)

(এটি অবশ্যই সম্ভব যে আমার অ্যানিমেশন বোধগম্যতার মধ্যে আমার এখনও ফাঁক রয়েছে এবং আমি প্যারেন্টিথিকাল স্টেটমেন্ট পছন্দ করি)

নেট প্রভাব যে leftস্ক্রীন বন্ধ স্লাইডসে middleমূল অবস্থান এবং আকারের স্লাইড left, এবং rightডান পিছনে মধ্যে অনুবাদ করে middle

showLeft() কেবলমাত্র অ্যানিমেটরগুলির একই মিশ্রণের সাথে প্রক্রিয়াটিকে বিপরীত করে দেয় ঠিক दिशाগুলি উল্টো করে দেয়।

ক্রিয়াকলাপটি ThreePaneLayoutএকজোড়া ListFragmentউইজেট ধরে রাখতে একটি ব্যবহার করে এবং এ Button। বাম খণ্ডে কিছু নির্বাচন করা মধ্যম খণ্ডকে যুক্ত করে (বা এর সামগ্রীগুলি আপডেট করে)। মাঝের খণ্ডে কিছু নির্বাচন করা এর ক্যাপশন সেট করে Button, এবং এর সাথে এক্সিকিউট hideLeft()করে ThreePaneLayout। BACK টিপুন, যদি আমরা বাম দিকটি লুকিয়ে রাখি তবে কার্যকর হবে showLeft(); অন্যথায়, ব্যাক ক্রিয়াকলাপ থেকে প্রস্থান করে। যেহেতু FragmentTransactionsএটি অ্যানিমেশনগুলিকে প্রভাবিত করার জন্য ব্যবহার করে না , তাই আমরা নিজেরাই "ব্যাক স্ট্যাক" পরিচালনা করতে আটকে আছি।

উপরে সংযুক্ত প্রকল্পটি নেটিভ টুকরা এবং নেটিভ অ্যানিমেটার ফ্রেমওয়ার্ক ব্যবহার করে। অ্যানিমেশনটির জন্য আমার কাছে একই প্রকল্পের অন্য একটি সংস্করণ রয়েছে যা অ্যান্ড্রয়েড সাপোর্ট টুকরা ব্যাকপোর্ট এবং নাইনওয়েলড্রয়েডগুলি ব্যবহার করে:

https://github.com/commonsguy/cw-omnibus/tree/master/Animation/ThreePaneBC

ব্যাকপোর্টটি প্রথম প্রজন্মের কিন্ডল ফায়ারে সূক্ষ্মভাবে কাজ করে, যদিও অ্যানিমেশনটি নিম্নতম হার্ডওয়্যার স্পেস এবং হার্ডওয়্যার ত্বরণ সমর্থনের অভাবের কারণে সামান্য বিড়ম্বনাযুক্ত। উভয় বাস্তবায়ন একটি নেক্সাস 7 এবং অন্যান্য বর্তমান প্রজন্মের ট্যাবলেটগুলিতে মসৃণ বলে মনে হচ্ছে।

আমি কীভাবে এই সমাধানটি উন্নত করতে পারি তার ধারণাগুলি বা আমি এখানে যা করেছি (বা @ উইকওয়ায়ার কী ব্যবহার করেছেন) তার থেকে সুস্পষ্ট সুবিধা দেয় এমন অন্যান্য সমাধানের জন্য অবশ্যই আমি উন্মুক্ত।

যারা অবদান রেখেছেন তাদের সবাইকে আবার ধন্যবাদ!


1
ওহে! সমাধানের জন্য ধন্যবাদ, তবে আমি মনে করি, v.setLayerType () যুক্ত করা কখনও কখনও জিনিসগুলিকে কিছুটা ধীর করে তোলে। কেবল এই রেখাগুলি সরিয়ে দিন (এবং শ্রোতারাও) এটি কমপক্ষে সত্যই Android 3+ ডিভাইসের জন্য আমি স্রেফ গ্যালাক্সি নেক্সাসে চেষ্টা করেছি এবং এই লাইনগুলি ছাড়া এটি আরও ভাল কাজ করছে
Evgeny Nacu

1
"দুটি বাস্তবায়নই একটি নেক্সাস 7 এবং অন্যান্য বর্তমান প্রজন্মের ট্যাবলেটগুলিতে মসৃণ বলে মনে হচ্ছে।" আমি তোমাকে বিশ্বাস করি; তবে আমি আপনার বাস্তবায়নটি একটি নেক্সাস 7 এ নেটিভ অবজেক্ট অ্যানিম্যাটরের সাথে পরীক্ষা করছি এবং এটি কিছুটা পিছিয়ে। সবচেয়ে সম্ভাব্য কারণগুলি কী হতে পারে? আমার ইতিমধ্যে হার্ডওয়্যার অ্যাক্সিলারেটেড রয়েছে: অ্যান্ড্রয়েড ম্যানিফেস্টে সত্য। সমস্যাটি কী হতে পারে তা আমি সত্যিই জানি না। আমি ড্যানিয়েলগ্রেকের বৈকল্পিকও চেষ্টা করেছি এবং এটি একই রকম পরে। আমি অ্যানিমেশনে পার্থক্য দেখতে পাচ্ছি (তার অ্যানিমেশনটি ওজনের উপর ভিত্তি করে) তবে কেন এটি উভয় ক্ষেত্রে পিছিয়ে থাকবে তা আমি দেখতে পাচ্ছি না।
বোগদান জুড়াক

1
@ অ্যান্ড্রু: "এটি কিছুটা পিছিয়ে যায়" - আপনি এখানে "ল্যাগ" ক্রিয়াটি কীভাবে ব্যবহার করছেন তা আমি অনিশ্চিত। আমার কাছে, "ল্যাগ" তুলনা করার জন্য একটি দৃ concrete় লক্ষ্যকে বোঝায়। সুতরাং, উদাহরণস্বরূপ, একটি সোয়াইপিং মোশনে আবদ্ধ অ্যানিমেশন আঙুলের চলাচলে পিছিয়ে থাকতে পারে। এই ক্ষেত্রে, সমস্ত কিছু টেপ দ্বারা চালিত হয় এবং তাই অ্যানিমেশনটি কী পিছনে থাকতে পারে তা আমি অস্পষ্ট। অনুমান করা যে সম্ভবত "কিছুটা পিছিয়ে গেছে" এর অর্থ হ'ল "স্বাচ্ছন্দ্য বোধ হয়", আমি এটি দেখিনি, তবে আমি দৃ strong় নান্দনিক বোধের দাবি করি না, এবং তাই আমার কাছে গ্রহণযোগ্য অ্যানিমেশন কী হতে পারে তা আপনার কাছে গ্রহণযোগ্য নয়।
কমন্সওয়্যার

2
@ কমন্সওয়্যার: আমি আপনার কোডটি 4.2, দুর্দান্ত কাজের সাথে সংকলিত করেছি। আমি যখন মাঝখানে টেপ করেছি ListViewএবং দ্রুত ফিরে বার বোতামটি টিপলাম এবং পুনরাবৃত্তি করব তখন পুরো লেআউট ডানদিকে প্রবাহিত হবে। এটি বাম দিকে অতিরিক্ত স্থান কলাম দেখানো শুরু করে। এই আচরণটি এমনভাবে প্রবর্তিত হয়েছিল কারণ আমি প্রথম অ্যানিমেশনটি (মাঝখানে ট্যাপ করে শুরু করা ListView) পুরোপুরি বোতামটি টিপতে এবং চাপতে দেব না । আমি প্রতিস্থাপন করে এটি সংশোধন করা হয়েছে translationXByসঙ্গে translationXtranslateWidgetsপদ্ধতি এবং translateWidgets(leftWidth, left, middle, right);সঙ্গে translateWidgets(0, left, middle, right);showLeft()পদ্ধতি।
এম-ওয়াজেইহ

2
আমিও প্রতিস্থাপিত requestLayout();সঙ্গে middle.requestLayout();setMiddleWidth(int value);পদ্ধতি। এটি জিপিইউ এখনও একটি সম্পূর্ণ লেআউট পাস করবে এমন কোনও অনুমান হিসাবে, পারফরম্যান্সে প্রভাব ফেলতে পারে না?
এম-ওয়াজেএইচ

13

আমরা পানেসলিবারি নামে একটি গ্রন্থাগার তৈরি করেছি যা এই সমস্যার সমাধান করে। পূর্বে যা দেওয়া হয়েছিল তার চেয়ে এটি আরও নমনীয় কারণ:

  • প্রতিটি ফলকটি গতিশীল আকারের হতে পারে
  • এটি কোনও সংখ্যক প্যানের জন্য অনুমতি দেয় (কেবল ২ বা 3 নয়)
  • ফলকের অভ্যন্তরের খণ্ডগুলি সঠিকভাবে ওরিয়েন্টেশন পরিবর্তনের উপর বজায় রাখা হয়।

আপনি এখানে এটি পরীক্ষা করে দেখতে পারেন: https://github.com/Mapsaurus/Android-PanesLibrary

এখানে একটি ডেমো রয়েছে: http://www.youtube.com/watch?v=UA-lAGVXoLU&fe चर =youtu.be

এটি মূলত আপনাকে সহজেই সংখ্যক গতিময় আকারের প্যানগুলি যুক্ত করতে এবং সেই ফলকের সাথে খণ্ডগুলি সংযুক্ত করার অনুমতি দেয়। আশা করি আপনি এটি দরকারী পাবেন! :)


6

আপনি ( http://android.amberfog.com/?p=758 ) এর সাথে সংযুক্ত উদাহরণগুলির মধ্যে একটিটি তৈরি করে কীভাবে layout_weightসম্পত্তিটি অ্যানিমেট করা যায় ? এইভাবে, আপনি একসাথে 3 টুকরা ওজনের পরিবর্তনকে অ্যানিমেট করতে পারেন এবং আপনি যে বোনাসটি পেয়েছেন তারা সকলেই একসাথে সুন্দরভাবে স্লাইড করে:

একটি সাধারণ বিন্যাস দিয়ে শুরু করুন। যেহেতু আমরা অ্যানিমেট করতে যাচ্ছি layout_weight, LinearLayoutতাই আমাদের 3 টি প্যানেলের রুট ভিউ হিসাবে একটি প্রয়োজন :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:id="@+id/panel1"
    android:layout_width="0dip"
    android:layout_weight="1"
    android:layout_height="match_parent"/>

<LinearLayout
    android:id="@+id/panel2"
    android:layout_width="0dip"
    android:layout_weight="2"
    android:layout_height="match_parent"/>

<LinearLayout
    android:id="@+id/panel3"
    android:layout_width="0dip"
    android:layout_weight="0"
    android:layout_height="match_parent"/>
</LinearLayout>

তারপরে ডেমো ক্লাস:

public class DemoActivity extends Activity implements View.OnClickListener {
    public static final int ANIM_DURATION = 500;
    private static final Interpolator interpolator = new DecelerateInterpolator();

    boolean isCollapsed = false;

    private Fragment frag1, frag2, frag3;
    private ViewGroup panel1, panel2, panel3;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        panel1 = (ViewGroup) findViewById(R.id.panel1);
        panel2 = (ViewGroup) findViewById(R.id.panel2);
        panel3 = (ViewGroup) findViewById(R.id.panel3);

        frag1 = new ColorFrag(Color.BLUE);
        frag2 = new InfoFrag();
        frag3 = new ColorFrag(Color.RED);

        final FragmentManager fm = getFragmentManager();
        final FragmentTransaction trans = fm.beginTransaction();

        trans.replace(R.id.panel1, frag1);
        trans.replace(R.id.panel2, frag2);
        trans.replace(R.id.panel3, frag3);

        trans.commit();
    }

    @Override
    public void onClick(View view) {
        toggleCollapseState();
    }

    private void toggleCollapseState() {
        //Most of the magic here can be attributed to: http://android.amberfog.com/?p=758

        if (isCollapsed) {
            PropertyValuesHolder[] arrayOfPropertyValuesHolder = new PropertyValuesHolder[3];
            arrayOfPropertyValuesHolder[0] = PropertyValuesHolder.ofFloat("Panel1Weight", 0.0f, 1.0f);
            arrayOfPropertyValuesHolder[1] = PropertyValuesHolder.ofFloat("Panel2Weight", 1.0f, 2.0f);
            arrayOfPropertyValuesHolder[2] = PropertyValuesHolder.ofFloat("Panel3Weight", 2.0f, 0.0f);
            ObjectAnimator localObjectAnimator = ObjectAnimator.ofPropertyValuesHolder(this, arrayOfPropertyValuesHolder).setDuration(ANIM_DURATION);
            localObjectAnimator.setInterpolator(interpolator);
            localObjectAnimator.start();
        } else {
            PropertyValuesHolder[] arrayOfPropertyValuesHolder = new PropertyValuesHolder[3];
            arrayOfPropertyValuesHolder[0] = PropertyValuesHolder.ofFloat("Panel1Weight", 1.0f, 0.0f);
            arrayOfPropertyValuesHolder[1] = PropertyValuesHolder.ofFloat("Panel2Weight", 2.0f, 1.0f);
            arrayOfPropertyValuesHolder[2] = PropertyValuesHolder.ofFloat("Panel3Weight", 0.0f, 2.0f);
            ObjectAnimator localObjectAnimator = ObjectAnimator.ofPropertyValuesHolder(this, arrayOfPropertyValuesHolder).setDuration(ANIM_DURATION);
            localObjectAnimator.setInterpolator(interpolator);
            localObjectAnimator.start();
        }
        isCollapsed = !isCollapsed;
    }

    @Override
    public void onBackPressed() {
        //TODO: Very basic stack handling. Would probably want to do something relating to fragments here..
        if(isCollapsed) {
            toggleCollapseState();
        } else {
            super.onBackPressed();
        }
    }

    /*
     * Our magic getters/setters below!
     */

    public float getPanel1Weight() {
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)     panel1.getLayoutParams();
        return params.weight;
    }

    public void setPanel1Weight(float newWeight) {
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) panel1.getLayoutParams();
        params.weight = newWeight;
        panel1.setLayoutParams(params);
    }

    public float getPanel2Weight() {
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) panel2.getLayoutParams();
        return params.weight;
    }

    public void setPanel2Weight(float newWeight) {
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) panel2.getLayoutParams();
        params.weight = newWeight;
        panel2.setLayoutParams(params);
    }

    public float getPanel3Weight() {
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) panel3.getLayoutParams();
        return params.weight;
    }

    public void setPanel3Weight(float newWeight) {
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) panel3.getLayoutParams();
        params.weight = newWeight;
        panel3.setLayoutParams(params);
    }


    /**
     * Crappy fragment which displays a toggle button
     */
    public static class InfoFrag extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle     savedInstanceState) {
            LinearLayout layout = new LinearLayout(getActivity());
            layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
            layout.setBackgroundColor(Color.DKGRAY);

            Button b = new Button(getActivity());
            b.setOnClickListener((DemoActivity) getActivity());
            b.setText("Toggle Me!");

            layout.addView(b);

            return layout;
        }
    }

    /**
     * Crappy fragment which just fills the screen with a color
     */
    public static class ColorFrag extends Fragment {
        private int mColor;

        public ColorFrag() {
            mColor = Color.BLUE; //Default
        }

        public ColorFrag(int color) {
            mColor = color;
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            FrameLayout layout = new FrameLayout(getActivity());
            layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

            layout.setBackgroundColor(mColor);
            return layout;
        }
    }
}

এছাড়াও এই উদাহরণটি অ্যানিমেশনগুলি অর্জন করার জন্য ফ্র্যাগমেন্ট ট্রান্সঅ্যাকশনগুলি ব্যবহার করে না (বরং এটি টুকরোগুলির সাথে সংযুক্ত দৃশ্যের অ্যানিমেট করে), সুতরাং আপনাকে সমস্ত ব্যাকস্ট্যাক / খণ্ডের লেনদেন নিজেই করতে হবে, তবে অ্যানিমেশনগুলি কাজ করার চেষ্টার সাথে তুলনা করতে হবে সুন্দরভাবে, এটি খারাপ ব্যবসা বন্ধ বলে মনে হচ্ছে না :)

এটির জন্য ভয়ঙ্কর কম-রেজির ভিডিও: http://youtu.be/Zm517j3bFCo


1
ঠিক আছে, জিমেইল অবশ্যই আমি ফ্রেগমেন্ট এ হিসাবে বর্ণনা করেছি তার অনুবাদ করেছে আমি আশঙ্কা করব যে এর ওজন 0 থেকে কমিয়ে দেওয়া ভিজ্যুয়াল আর্টফিটগুলি প্রবর্তন করতে পারে (যেমন, অ্যানিমেশনটি এগিয়ে যাওয়ার TextViewসাথে সাথে wrap_contentনিজেকে উল্লম্বভাবে প্রসারিত করে)। যাইহোক, এটি হতে পারে যে ওজনকে অ্যানিমেট করাতে আমি ফ্রেগমেন্ট বি হিসাবে উল্লেখ করেছি সেটিকে তারা পুনরায় আকার দিন Thanks ধন্যবাদ!
কমন্সওয়্যার

1
কোন চিন্তা করো না! যদিও এটি একটি ভাল বিষয়, এটি সম্ভবত 'ফ্রেগমেন্ট এ' তে শিশুদের দৃষ্টিভঙ্গি নির্ভর করে ভিজ্যুয়াল আর্টিক্টসগুলির কারণ হতে পারে। আশা করি যে কেউ এটির জন্য আরও
দৃ

5

এটি খণ্ডগুলি ব্যবহার করছে না .... এটি 3 বাচ্চাদের সাথে একটি কাস্টম বিন্যাস layout আপনি যখন কোনও বার্তায় ক্লিক করেন, আপনি 3 টি শিশু offsetLeftAndRight()এবং অ্যানিমেটার ব্যবহার করে অফসেট করেন ।

ইন JellyBeanকরতে সক্ষম করতে পারেন "Developper বিকল্প" সেটিংসে "দেখান সীমা লেআউট"। স্লাইড অ্যানিমেশনটি সম্পূর্ণ হয়ে গেলে, আপনি এখনও দেখতে পাবেন যে বাম মেনুটি এখনও রয়েছে, তবে মাঝের প্যানেলের নীচে।

এটি সিরিল মোটটিয়ের ফ্লাই-ইন অ্যাপ্লিকেশন মেনুর মতো , তবে 2 এর পরিবর্তে 3 টি উপাদান রয়েছে।

সংযোজন হিসাবে, ViewPagerতৃতীয় সন্তানের মধ্যে এই আচরণের আরেকটি ইঙ্গিত: ViewPagerসাধারণত খণ্ডগুলি ব্যবহার করে (আমি জানি তাদের এটি করার দরকার নেই, তবে আমি এর আগে কখনও বাস্তবায়ন দেখিনি Fragment), এবং যেহেতু আপনি Fragmentsঅন্য Fragmentতিনটি সন্তানের ভিতরে ব্যবহার করতে পারবেন না সম্ভবত টুকরা না ....


আমি এর আগে কখনও "লেআউট সীমা দেখান" ব্যবহার করি নি - এটি ক্লোজড-সোর্স অ্যাপ্লিকেশনগুলির জন্য খুব সহায়ক (ধন্যবাদ!) এটি প্রদর্শিত হয় যা আমি ফ্র্যাগমেন্ট এ হিসাবে বর্ণনা করেছি তা অফ-স্ক্রিনটি অনুবাদ করছে (আপনি তার ডান প্রান্তের স্লাইডটি ডান থেকে বাম দেখতে পাচ্ছেন), যা ফ্রেমমেন্ট বি হিসাবে বর্ণনা করেছেন তার নীচে ফিরে পপ করার আগে এটি মনে হয় TranslateAnimation, যদিও আমি নিশ্চিতভাবে একই প্রান্তটি সম্পাদন করতে অ্যানিমেটারগুলি ব্যবহার করার উপায় রয়েছে। আমাকে এ নিয়ে কিছু পরীক্ষা চালাতে হবে। ধন্যবাদ!
কমন্সওয়্যার

2

উপলব্ধ স্থানটি গ্রহণের জন্য ফ্রেগমেন্ট বি স্কেল ব্যতীত এবং পর্যাপ্ত জায়গা থাকলে 3 টি ফলকটি একই সময়ে খোলা যেতে পারে except সেজন্য আমি বর্তমানে সেরকম কিছু করার চেষ্টা করছি। এখানে এখন পর্যন্ত আমার সমাধানটি রয়েছে তবে আমি নিশ্চিত নই যে আমি এটির সাথে লেগে যাব কিনা। আমি আশা করি কেউ সঠিক উত্তর প্রদর্শন করে একটি উত্তর সরবরাহ করবে।

লিনিয়ারলআউট ব্যবহার ও ওজন অ্যানিমেট করার পরিবর্তে আমি একটি রিলেটিভলআউট ব্যবহার করি এবং মার্জিনগুলি অ্যানিমেট করি। আমি নিশ্চিত নই যে এটি সর্বোত্তম উপায় কারণ এটি প্রতিটি আপডেটে লায়আউট () এর অনুরোধের জন্য কল প্রয়োজন। যদিও এটি আমার সমস্ত ডিভাইসে মসৃণ।

সুতরাং, আমি লেআউটটি অ্যানিমেটেড করছি, আমি টুকরাক লেনদেন ব্যবহার করছি না। আমি পিছনের বোতামটি ম্যানুয়ালি হ্যান্ডেল করে খণ্ড খ সিটি বন্ধ করে রাখি।

ফ্রেগমেন্টবি লে এবং লেফটঅফ / ট্যরাইটঅফটিকে এটিকে এবং খণ্ড খণ্ডে রেখাযুক্ত রাখতে ব্যবহার করে

যখন আমার অ্যাপ্লিকেশনটি খণ্ডন সি প্রদর্শন করার জন্য কোনও ইভেন্ট ট্রিগার করে, আমি ফ্রেমে-ইন ফ্রেগমেন্ট সি করি এবং আমি একই সাথে টুকরোটি স্লাইড আউট করে। (2 পৃথক অ্যানিমেশন)। বিপরীতভাবে, যখন খণ্ড A খোলা হয়, আমি একই সাথে সি বন্ধ করি।

প্রতিকৃতি মোডে বা ছোট স্ক্রিনে, আমি স্ক্রিনের উপরে কিছুটা আলাদা লেআউট এবং স্লাইড ফ্রেগমেন্ট সি ব্যবহার করি।

খণ্ড A এবং C এর প্রস্থের শতাংশের জন্য, আমি মনে করি আপনাকে রান সময় এটি গণনা করতে হবে ... (?)

ক্রিয়াকলাপের লেআউটটি এখানে:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootpane"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <!-- FRAGMENT A -->
    <fragment
        android:id="@+id/fragment_A"
        android:layout_width="300dp"
        android:layout_height="fill_parent"
        class="com.xyz.fragA" />

    <!-- FRAGMENT C -->
    <fragment
        android:id="@+id/fragment_C"
        android:layout_width="600dp"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        class="com.xyz.fragC"/>

    <!-- FRAGMENT B -->
    <fragment
        android:id="@+id/fragment_B"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:layout_marginLeft="0dip"
        android:layout_marginRight="0dip"
        android:layout_toLeftOf="@id/fragment_C"
        android:layout_toRightOf="@id/fragment_A"
        class="com.xyz.fragB" />

</RelativeLayout>

ফ্রেগমেন্ট সি স্লাইড করতে বা এনিমেশন এনিমেশন:

private ValueAnimator createFragmentCAnimation(final View fragmentCRootView, boolean slideIn) {

    ValueAnimator anim = null;

    final RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) fragmentCRootView.getLayoutParams();
    if (slideIn) {
        // set the rightMargin so the view is just outside the right edge of the screen.
        lp.rightMargin = -(lp.width);
        // the view's visibility was GONE, make it VISIBLE
        fragmentCRootView.setVisibility(View.VISIBLE);
        anim = ValueAnimator.ofInt(lp.rightMargin, 0);
    } else
        // slide out: animate rightMargin until the view is outside the screen
        anim = ValueAnimator.ofInt(0, -(lp.width));

    anim.setInterpolator(new DecelerateInterpolator(5));
    anim.setDuration(300);
    anim.addUpdateListener(new AnimatorUpdateListener() {

        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            Integer rightMargin = (Integer) animation.getAnimatedValue();
            lp.rightMargin = rightMargin;
            fragmentCRootView.requestLayout();
        }
    });

    if (!slideIn) {
        // if the view was sliding out, set visibility to GONE once the animation is done
        anim.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationEnd(Animator animation) {
                fragmentCRootView.setVisibility(View.GONE);
            }
        });
    }
    return anim;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.