2016-11-03 42 views

Odpowiedz

5

Zrobiłem szybki atrapę aplikację, która wygląda jak twoje, i starał się osiągnąć tego, co zostało pokazane w animacji. Zobaczyć efekt poniżej (można uczynić go bardziej gładki i elegancki):

enter image description here

Jest nieco kłopotliwe ze sposobów, tak zrobiłem. I pisać cały mój kod tutaj:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.pabhinav.testapp3"> 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <activity 
      android:name=".MainActivity" 
      android:label="@string/app_name" 
      android:screenOrientation="portrait" 
      android:theme="@style/AppTheme.NoActionBar"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 


MainActivity.java

package com.pabhinav.testapp3; 

import android.os.Bundle; 
import android.support.design.widget.TabLayout; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentPagerAdapter; 
import android.support.v4.view.ViewPager; 
import android.support.v7.app.AppCompatActivity; 
import android.util.DisplayMetrics; 
import android.util.TypedValue; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.animation.Animation; 
import android.view.animation.AnimationSet; 
import android.view.animation.LinearInterpolator; 
import android.view.animation.ScaleAnimation; 
import android.view.animation.TranslateAnimation; 
import android.widget.EditText; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.RelativeLayout; 

import static com.pabhinav.testapp3.R.id.container; 

public class MainActivity extends AppCompatActivity implements PlaceholderFragment.OnSearchBoxClick{ 

    /** 
    * The {@link android.support.v4.view.PagerAdapter} that will provide 
    * fragments for each of the sections. We use a 
    * {@link FragmentPagerAdapter} derivative, which will keep every 
    * loaded fragment in memory. If this becomes too memory intensive, it 
    * may be best to switch to a 
    * {@link android.support.v4.app.FragmentStatePagerAdapter}. 
    */ 
    private SectionsPagerAdapter mSectionsPagerAdapter; 

    /** 
    * The {@link ViewPager} that will host the section contents. 
    */ 
    private ViewPager mViewPager; 

    /** 
    * Search Box in activity. 
    */ 
    private RelativeLayout dummySearchBox; 

    private LinearLayout topSearchBox; 

    /** 
    * Overlay View appears when search box is clicked. 
    */ 
    private View overlay; 

    /** 
    * Back button image view for top search box 
    */ 
    private ImageView backButtonSearchBox; 

    /** 
    * PlaceHolderFragment saved only for second tab, 
    * which has search box. 
    */ 
    private PlaceholderFragment placeholderFragment; 

    private float xDelta, yDelta; 

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

     // Create the adapter that will return a fragment for each of the three 
     // primary sections of the activity. 
     mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); 
     getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark)); 
     overlay = findViewById(R.id.overlay_whole_page); 
     backButtonSearchBox = (ImageView)findViewById(R.id.search_icon); 

     // Consume touch event, so that it does not pass to parent views. 
     // This is done to block swipe events of tab layout, once search 
     // box is clicked. 
     overlay.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       return true; 
      } 
     }); 

     // TabLayout and ViewPager. 
     final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); 
     mViewPager = (ViewPager) findViewById(container); 
     dummySearchBox = (RelativeLayout)findViewById(R.id.dummy_search_box); 
     topSearchBox = (LinearLayout)findViewById(R.id.top_search_box); 

     // Set up the ViewPager with the sections adapter. 
     mViewPager.setAdapter(mSectionsPagerAdapter); 
     mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
      @Override 
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {} 

      @Override 
      public void onPageSelected(int position) { 
       for (int i = 0; i < tabLayout.getTabCount(); i++) { 
        if(i == position){ 
         tabLayout.getTabAt(i).setIcon(getTabIconHighlighted(i)); 
        } else { 
         tabLayout.getTabAt(i).setIcon(getTabIconUnhighlighted(i)); 
        } 
       } 
      } 

      @Override 
      public void onPageScrollStateChanged(int state) {} 
     }); 

     // Setup viewpager with tablayout and also set up icons of each tabs : 
     tabLayout.setupWithViewPager(mViewPager); 
     for(int i = 0; i<tabLayout.getTabCount(); i++){ 

      // Set first tab highlighted : 
      if(i == 0){ 
       tabLayout.getTabAt(i).setIcon(getTabIconHighlighted(i)); 
      } else { 
       tabLayout.getTabAt(i).setIcon(getTabIconUnhighlighted(i)); 
      } 
     } 

     // Back Button in top search box clicked. 
     backButtonSearchBox.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       overlay.setVisibility(View.INVISIBLE); 
       dummySearchBox.setVisibility(View.VISIBLE); 
       topSearchBox.setVisibility(View.INVISIBLE); 

       AnimationSet animSet = new AnimationSet(true); 
       animSet.setFillAfter(false); 
       animSet.setDuration(150); 
       animSet.setInterpolator(new LinearInterpolator()); 
       TranslateAnimation translate = new TranslateAnimation(-xDelta, 0, -yDelta, 0); 
       animSet.addAnimation(translate); 
       ScaleAnimation scale = new ScaleAnimation(1.2f, 1f, 1.2f, 1f); 
       animSet.addAnimation(scale); 
       dummySearchBox.startAnimation(animSet); 
       animSet.setAnimationListener(new Animation.AnimationListener() { 
        @Override 
        public void onAnimationStart(Animation animation) { 

        } 

        @Override 
        public void onAnimationEnd(Animation animation) { 
         placeholderFragment.showSearchLayout(); 
         dummySearchBox.setVisibility(View.INVISIBLE); 
        } 

        @Override 
        public void onAnimationRepeat(Animation animation) { 

        } 
       }); 
      } 
     }); 
    } 

    private int getTabIconUnhighlighted(int position){ 
     switch (position){ 
      case 0 : return R.drawable.ic_home_black_24dp; 
      case 1 : return R.drawable.ic_search_black_24dp; 
      case 2 : return R.drawable.ic_heart_black_24dp; 
      case 3 : return R.drawable.ic_view_headline_black_24dp; 
     } 
     return -1; 
    } 

    private int getTabIconHighlighted(int position){ 
     switch(position){ 
      case 0 : return R.drawable.ic_home_highlighted_24dp; 
      case 1 : return R.drawable.ic_search_highlighted_24dp; 
      case 2 : return R.drawable.ic_heart_highlighted_24dp; 
      case 3 : return R.drawable.ic_view_headline_highlighted_24dp; 
     } 
     return -1; 
    } 

    /** 
    * This event is when search box from fragment is clicked, 
    * need to animate the search box present in activity 
    * to reach the top of activity display. 
    */ 
    @Override 
    public void onClick() { 
     dummySearchBox.setVisibility(View.VISIBLE); 
     dummySearchBox.clearFocus(); 
     ((EditText)findViewById(R.id.search_edit_text)).clearFocus(); 
     performAnimation(dummySearchBox); 
    } 

    public void performAnimation(final RelativeLayout dummySearchBox){ 

     if(xDelta == 0 && yDelta == 0){ 
      DisplayMetrics dm = new DisplayMetrics(); 
      getWindowManager().getDefaultDisplay().getMetrics(dm); 
      int[] originalPos = new int[2]; 
      dummySearchBox.getLocationOnScreen(originalPos); 

      xDelta = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 18, getResources().getDisplayMetrics()); 
      yDelta = originalPos[1] - TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12, getResources().getDisplayMetrics());; 
     } 

     AnimationSet animSet = new AnimationSet(true); 
     animSet.setFillAfter(false); 
     animSet.setDuration(200); 
     animSet.setInterpolator(new LinearInterpolator()); 
     TranslateAnimation translate = new TranslateAnimation(0, -1*xDelta, 0, -1*yDelta); 
     animSet.addAnimation(translate); 
     ScaleAnimation scale = new ScaleAnimation(1f, 1.15f, 1f, 1.15f); 
     animSet.addAnimation(scale); 
     dummySearchBox.startAnimation(animSet); 
     animSet.setAnimationListener(new Animation.AnimationListener() { 
      @Override 
      public void onAnimationStart(Animation animation) { 

      } 

      @Override 
      public void onAnimationEnd(Animation animation) { 

       topSearchBox.setVisibility(View.VISIBLE); 
       dummySearchBox.setVisibility(View.INVISIBLE); 
       overlay.setVisibility(View.VISIBLE); 
      } 

      @Override 
      public void onAnimationRepeat(Animation animation) { 

      } 
     }); 
    } 

    /** 
    * A {@link FragmentPagerAdapter} that returns a fragment corresponding to 
    * one of the sections/tabs/pages. 
    */ 
    public class SectionsPagerAdapter extends FragmentPagerAdapter { 

     /** 
     * The fragment argument representing the section number for this 
     * fragment. 
     */ 
     public static final String ARG_SECTION_NUMBER = "section_number"; 

     public SectionsPagerAdapter(FragmentManager fm) { 
      super(fm); 
     } 

     @Override 
     public Fragment getItem(int position) { 
      // getItem is called to instantiate the fragment for the given page. 
      // Return a PlaceholderFragment. 
      PlaceholderFragment placeholderFragment = new PlaceholderFragment(); 
      placeholderFragment.setOnSearchBoxClick(MainActivity.this); 
      Bundle args = new Bundle(); 
      args.putInt(ARG_SECTION_NUMBER, position + 1); 
      placeholderFragment.setArguments(args); 
      if(position == 1){ 
       MainActivity.this.placeholderFragment = placeholderFragment; 
      } 
      return placeholderFragment; 
     } 

     @Override 
     public int getCount() { 
      // Show 4 total pages. 
      return 4; 
     } 
    } 
} 

PlaceholderFragment.java

package com.pabhinav.testapp3; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.TextView; 

/** 
* @author pabhinav 
*/ 

public class PlaceholderFragment extends Fragment { 

    private LinearLayout searchLayout; 

    public PlaceholderFragment() { 
    } 

    private OnSearchBoxClick onSearchBoxClick; 
    public void setOnSearchBoxClick(OnSearchBoxClick onSearchBoxClick){ 
     this.onSearchBoxClick = onSearchBoxClick; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     int sectionNumber = getArguments().getInt(MainActivity.SectionsPagerAdapter.ARG_SECTION_NUMBER); 
     View rootView = inflater.inflate((sectionNumber == 2) ? R.layout.fragment_search : R.layout.fragment_main, container, false); 
     if(sectionNumber != 2) { 
      TextView textView = (TextView) rootView.findViewById(R.id.section_label); 
      textView.setText(getString(R.string.section_format, sectionNumber)); 
     } else { 

      // Its the fragment with search box : 
      TextView searchText = (TextView) rootView.findViewById(R.id.search_text); 
      ImageView searchIcon = (ImageView)rootView.findViewById(R.id.search_icon); 
      searchLayout = (LinearLayout)rootView.findViewById(R.id.search_linear_layout); 

      // Need to do transition when clicked on any of the search box elements : 
      View.OnClickListener clickListener = new View.OnClickListener(){ 
       @Override 
       public void onClick(View v) { 
        searchLayout.setVisibility(View.INVISIBLE); 
        if(onSearchBoxClick != null) 
         onSearchBoxClick.onClick(); 
       } 
      }; 
      searchText.setOnClickListener(clickListener); 
      searchLayout.setOnClickListener(clickListener); 
      searchIcon.setOnClickListener(clickListener); 
     } 
     return rootView; 
    } 

    public void showSearchLayout(){ 
     searchLayout.setVisibility(View.VISIBLE); 
    } 

    public interface OnSearchBoxClick{ 
     public void onClick(); 
    } 
} 


activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/main_content" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:fitsSystemWindows="true" 
    tools:context="com.pabhinav.testapp3.MainActivity"> 

    <android.support.design.widget.TabLayout 
     android:layout_marginTop="8dp" 
     android:id="@+id/tabs" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

    <!-- Top Search Box --> 
    <!-- Only appears when search box is clicked --> 
    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="56dp" 
     android:id="@+id/top_search_box" 
     android:visibility="invisible" 
     android:orientation="horizontal"> 

     <RelativeLayout 
      android:layout_gravity="center" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:background="@android:color/white"> 

      <ImageView 
       android:gravity = "center" 
       android:layout_width="52dp" 
       android:paddingLeft="24dp" 
       android:paddingRight="8dp" 
       android:id="@+id/search_icon" 
       android:layout_height="match_parent" 
       android:src="@drawable/ic_arrow_back_black_24dp"/> 

      <EditText 
       android:layout_toEndOf="@+id/search_icon" 
       android:hint="@string/search_soundcloud" 
       android:textSize="18sp" 
       android:background="@android:color/transparent" 
       android:textColorHint="#B3B3B3" 
       android:layout_margin="4dp" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" /> 

     </RelativeLayout> 

    </LinearLayout> 

    <!-- Dummy container for search box --> 
    <!-- This will do transition from its location to top_search_box location --> 
    <RelativeLayout 
     android:id="@+id/dummy_search_box" 
     android:layout_width="match_parent" 
     android:layout_below="@+id/tabs" 
     android:visibility="invisible" 
     android:layout_height="wrap_content" 
     android:padding="16dp"> 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="56dp" 
      android:id="@+id/search_linear_layout_dummy" 
      android:orientation="horizontal"> 

      <RelativeLayout 
       android:layout_gravity="center" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:layout_margin="5dp" 
       android:background="@android:color/white" 
       android:elevation="2dp" 
       android:translationZ="2dp"> 

       <ImageView 
        android:gravity = "center" 
        android:layout_width="20dp" 
        android:layout_marginStart="16dp" 
        android:id="@+id/search_icon_dummy" 
        android:layout_height="match_parent" 
        android:src="@drawable/ic_search_light_black_24dp"/> 

       <EditText 
        android:id="@+id/search_edit_text" 
        android:layout_toEndOf="@+id/search_icon_dummy" 
        android:hint="@string/search_soundcloud" 
        android:textSize="16sp" 
        android:background="@android:color/transparent" 
        android:textColorHint="#B3B3B3" 
        android:layout_margin="4dp" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent" /> 

      </RelativeLayout> 

     </LinearLayout> 

    </RelativeLayout> 


    <android.support.v4.view.ViewPager 
     android:layout_below="@+id/tabs" 
     android:id="@+id/container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 


    <!-- Dummy overlay over whole page, More things can be added like listview 
     which displays result of searched text --> 
    <View 
     android:id="@+id/overlay_whole_page" 
     android:layout_below="@+id/tabs" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:visibility="gone" 
     android:background="#72000000" /> 

    <!-- Dummy shadow below tablayout --> 
    <View 
     android:layout_width="match_parent" 
     android:layout_height="1dp" 
     android:layout_below="@+id/tabs" 
     android:background="#42000000" /> 



</RelativeLayout> 

fragment_search.xml

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.pabhinav.testapp3.MainActivity$PlaceholderFragment"> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="56dp" 
     android:id="@+id/search_linear_layout" 
     android:orientation="horizontal"> 

     <RelativeLayout 
      android:layout_gravity="center" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_margin="5dp" 
      android:background="@android:color/white" 
      android:elevation="2dp" 
      android:translationZ="2dp"> 

      <ImageView 
       android:gravity = "center" 
       android:layout_width="20dp" 
       android:layout_marginStart="16dp" 
       android:id="@+id/search_icon" 
       android:layout_height="match_parent" 
       android:src="@drawable/ic_search_light_black_24dp"/> 

      <TextView 
       android:id="@+id/search_text" 
       android:layout_toEndOf="@+id/search_icon" 
       android:text="@string/search_soundcloud" 
       android:gravity="center_vertical" 
       android:textColor="#B3B3B3" 
       android:textSize="16sp" 
       android:layout_margin="4dp" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" /> 

     </RelativeLayout> 

    </LinearLayout> 

    <TextView 
     android:id="@+id/suggested_stations" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="56dp" 
     android:textSize="18sp" 
     android:layout_below="@+id/search_linear_layout" 
     android:text = "@string/suggested_stations"/> 

    <LinearLayout 
     android:layout_below="@+id/suggested_stations" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal"> 

     <ImageView 
      android:layout_width="0dp" 
      android:layout_height="240dp" 
      android:src="@drawable/image_1" 
      android:layout_weight="1"/> 

     <ImageView 
      android:layout_marginStart="16dp" 
      android:layout_width="0dp" 
      android:layout_height="240dp" 
      android:src="@drawable/image_2" 
      android:layout_weight="1"/> 

    </LinearLayout> 

</RelativeLayout> 


Pobierz cały projekt stąd: https://drive.google.com/file/d/0B_Mi44NWLWmyNFNkeHJ6cVBLTTg/view?usp=sharing

Nadzieję, że to pomaga!

+0

Już zaimplementowałem pole wyszukiwania i układ tab, i wszystko to, chcę tylko segment animacji, thanx dla twojego czasu, oznacz flagę do góry –

+0

Animacja jest nieco zhakowana, możesz uruchomić cały projekt, aby zobaczyć, czy animacja jest czego się spodziewałeś i aby dowiedzieć się, jak to zrobiłem, wystarczy spojrzeć na plik MainActivity.java. –

+0

OK, będę usmażyć w tej chwili, dziękuję za poświęcony czas. –