آموزش Parallax Scrollview در برنامه نویسی اندروید

سلام دوستان در این سری از آموزش برنامه نویسی اندروید به آموزش Parallax Scrollview در برنامه نویسی اندروید می پردازیم شاید نام دیگر Parallax Scrollview را به نام Observablescrollview شنیده باشید از این نوع Scrollview به منظور ایجاد نوع خاصی از scroll در برنامه استفاده می شود در ادامه می توانید پیش نمایشی از این نوع scroll را مشاهده کنید با ما همراه باشید.

برای استفاده از این آموزش لازم است سه کتاب خانه را به پروژه خود اضافه کنید.
برای اینکار وارد فایل Build.gradle از نوع Module شده سپس در بخش dependencies خط های زیر را اضافه کنید.

compile 'com.android.support:design:23.1.1'
compile 'com.github.ksoichiro:android-observablescrollview:1.5.0'
compile 'com.nineoldandroids:library:2.4.0'

پروژه را sync کنید.
اگر دقت کرده باشید یک عکس در زیر toolbar قرار گرفته بود می تواند در ادامه آن عکس را دانلود و در پوشه drawable قرار دهید.
لینک دانلود عکس
در همان پوشه drawable یک فایل به نام gradient_header_background.xml ایجاد کرده و کدهای زیر را در آن قرار دهید.

<shape xmlns:android="https://schemas.android.com/apk/res/android">
    <gradient
        android:angle="270"
        android:endColor="#00616161"
        android:startColor="#CC616161" />
</shape>

در همان پوشه یک فایل نام sliding_header_overlay.xml ایجاد کرده و کدهای زیر را در آن قرار دهید.

<shape xmlns:android="https://schemas.android.com/apk/res/android">
    <gradient
        android:angle="270"
        android:endColor="#00009688"
        android:startColor="#FF009688" />
</shape>

دو فایل بالا انیمیشن (تغییر رنگ) بین اسکرول , عکس  و toolbar را ایجاد می کند.
وارد مسیر res/values شده فایل colors.xml را باز کرده و رنگ های زیر را به آن اضافه کنید.

<resources>
    <color name="primary">#009688</color>
    <color name="primaryDark">#00796b</color>
    <color name="accent">#eeff41</color>
    <color name="accentLight">#F4FF81</color>
</resources>

در همان مسیر یک فایل به نام dimes.xml ایجاد کرده و کدهای زیر را در آن قرار دهید.

<resources>
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="margin_standard">16dp</dimen>
    <dimen name="margin_short">8dp</dimen>
    <dimen name="margin_extra_short">4dp</dimen>
    <dimen name="toolbar_elevation">4dp</dimen>
    <dimen name="toolbar_margin_start">72dp</dimen>
    <dimen name="flexible_space_height">72dp</dimen>
    <dimen name="flexible_space_image_height">240dp</dimen>
    <dimen name="flexible_space_show_fab_offset">120dp</dimen>
    <dimen name="parallax_image_height">180dp</dimen>
    <dimen name="tab_height">48dp</dimen>
    <dimen name="header_bar_height">72dp</dimen>
    <dimen name="intersection_height">16dp</dimen>
    <dimen name="sliding_slop">32dp</dimen>
    <dimen name="sliding_overlay_blur_size">4dp</dimen>
</resources>

وارد فایل string.xml شده و کدهای زیر را به آن اضافه کنید.

<resources>
    <string name="app_name">Programchi.ir</string>
    <string name="title_activity_main">Android ObservableScrollView</string>
    <string name="title_activity_about">About this app</string>
    <string name="title_activity_parallaxtoolbarscrollview">Parallax scrollView &amp; toolbar</string>
    <string name="title_activity_toolbarcontrolscrollview">ScrollView &amp; Toolbar</string>
    <string name="lipsum">With the aim of helping the community, we are providing free and useful resources, information, tips and tricks to learn Android development. We believe that education is a basic human right and hence we seek to make it possible for all people in the world to learn Android development without any hassle. This is one stop solution for both android developers and learners. Here at Android Tutorial Point we thrive to deliver the best tutorials. In this direction, we are trying to create a community that will cater to your needs, whether you are a beginner or a seasoned veteran. Learners can refer our basic tutorials and developers can refer Material Design, Networking and Intermediate tutorials. Stick with us for a while, and we promise you will become an Android Rockstar.Wanna part of this journey? Contact Us. You are most cordially invited to connect with us. Kapil Gupta: Kapil is a technology enthusiast with a wide knowledge base and experience with multiple programming languages. He is currently working with world’s second largest software company. He loves to create and automate stuff. He is fond of working on new and emerging technology. Due to his love for sharing knowledge, he is a part of android tutorial point team. Feel free to contact him on Facebook or LinkedIn. You can also mail him at kapilguptansit@gmail.com. Navneet Goel: Navneet is a Digital Marketing and Coding enthusiast with the heart of an entrepreneur. Passed out of NSIT Delhi in 2014, He is currently working in a multinational company as an RnD Engineer and used to write Android Tutorials in free time. He believes in giving back to society and hence started this blog. You are most welcome to connect with him on Facebook, Twitter or LinkedIn. You can also mail him at navneetgoel44@gmail.com. Android Logo - In 2007, the green Android logo was designed for Google by graphic designer Irina Blok. The design team was tasked with a project to create a universally identifiable icon with the specific inclusion of a robot in the final design. After numerous design developments based on science-fiction and space movies, the team eventually sought inspiration from the human symbol on restroom doors and modified the figure into a robot shape. As Android is open-sourced, it was agreed that the logo should be likewise, and since its launch the green logo has been reinterpreted into countless variations on the original design. Linux kernel - Android variant of the Linux kernel has further architectural changes that are implemented by Google outside the typical Linux kernel development cycle, such as the inclusion of components like Binder, ashmem, pmem, logger, wakelocks, and different out-of-memory handling.</string>
</resources>

در بالا یک string طولانی وجود دارد (برای ایکنه scroll به وجود بیایید)
وارد فایل styles.xml شده و آن را همانند زیر تغییر دهید.

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primaryDark</item>
        <item name="colorAccent">@color/accent</item>
    </style>
    <style name="AppTheme.Toolbar" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primaryDark</item>
        <item name="colorAccent">@color/accent</item>
    </style>
    <style name="Toolbar" parent="Theme.AppCompat">
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primaryDark</item>
        <item name="colorAccent">@color/accent</item>
    </style>
</resources>

ما دوتا اکتیویتی درست می کنیم در اولی که یک ListView در آن است همانند زیر (نام این اکتیویتی برابر با activity_main.xml است)

<LinearLayout
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical"
    >
    <android.support.v7.widget.Toolbar
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:minHeight="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:elevation="@dimen/toolbar_elevation"
        app:popupTheme="@style/Theme.AppCompat.Light.DarkActionBar"
        app:theme="@style/Toolbar"
        >
    </android.support.v7.widget.Toolbar>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ListView
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
    </FrameLayout>
</LinearLayout>

و یک layout دیگر به نام activity_parallaxtoolbarscrollview.xml ایجاد کرده و کدهای زیر را در آن قرار دهید.

<FrameLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.github.ksoichiro.android.observablescrollview.ObservableScrollView
        android:id="@+id/scroll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:id="@+id/image"
                android:layout_width="wrap_content"
                android:layout_height="@dimen/parallax_image_height"
                android:scaleType="centerCrop"
                android:src="@drawable/example" />
            <View
                android:id="@+id/anchor"
                android:layout_width="match_parent"
                android:layout_height="@dimen/parallax_image_height"
                android:minHeight="@dimen/parallax_image_height" />
            <TextView
                android:id="@+id/body"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/anchor"
                android:background="@android:color/white"
                android:paddingBottom="@dimen/activity_vertical_margin"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:text="@string/lipsum" />
        </RelativeLayout>
    </com.github.ksoichiro.android.observablescrollview.ObservableScrollView>
    <include layout="@layout/gradient_header" />
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        app:popupTheme="@style/Theme.AppCompat.Light.DarkActionBar"
        app:theme="@style/Toolbar" />
</FrameLayout>

در بالا یک layout دیگه تعریف شده است که با کلیک بروی اکتیویتی اول به اکتیویتی دوم منتقل می شوید.
حالا در پوشه layout یک فایل به نام gradient_header.xml ایجاد کرده و کدهای زیر را در آن قرار دهید.

<View xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@drawable/gradient_header_background"
    android:minHeight="?attr/actionBarSize" />

در همان پوشه یک فایل به نام list_item_main.xml ایجاد کرده و کدهای زیر را در آن قرار دهید.

<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:gravity="center_vertical"
              android:minHeight="?android:attr/listPreferredItemHeight"
              android:orientation="vertical"
              android:padding="6dp">
    <TextView
        android:id="@+id/className"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Activity class name"
        android:textAppearance="?android:attr/textAppearanceSmall" />
    <TextView
        android:id="@+id/description"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Description of the sample"
        android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>

حالا باید کد مربوط به اکتیویتی اول که نام آن برابر با MainActivity.java است را قرار دهیم.

package ir.programchi;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
    private static final String CATEGORY_SAMPLES = MainActivity.class.getPackage().getName();
    private static final String TAG_CLASS_NAME = "className";
    private static final String TAG_DESCRIPTION = "description";
    private static final String TAG_INTENT = "intent";
    private ListView listView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(android.R.id.list);
        listView.setOnItemClickListener(this);
        refreshData();
    }
    private void refreshData() {
        listView.setAdapter(new SimpleAdapter(this, getData(),
                R.layout.list_item_main,
                new String[]{TAG_CLASS_NAME, TAG_DESCRIPTION,},
                new int[]{R.id.className, R.id.description,}));
    }
    private List<Map<String, Object>> getData() {
        List<Map<String, Object>> data = new ArrayList<>();
        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
        mainIntent.setPackage(getApplicationContext().getPackageName());
        mainIntent.addCategory(CATEGORY_SAMPLES);
        PackageManager pm = getPackageManager();
        List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
        if (list == null) {
            return data;
        }
        addItem(data,
               "ParallaxToolbarScrollViewActivity",
                "Parallax scrollView & toolbar",
                activityIntent(
                        "ir.programchi.androidobservablescrollview",
                        "ir.programchi.androidobservablescrollview.ParallaxToolbarScrollViewActivity"));
        return data;
    }
    protected Intent activityIntent(String pkg, String componentName) {
        Intent result = new Intent();
        result.setClassName(pkg, componentName);
        return result;
    }
    protected void addItem(List<Map<String, Object>> data, String className, String description,
                           Intent intent) {
        Map<String, Object> temp = new HashMap<>();
        temp.put(TAG_CLASS_NAME, className);
        temp.put(TAG_DESCRIPTION, description);
        temp.put(TAG_INTENT, intent);
        data.add(temp);
    }
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Map<String, Object> map = (Map<String, Object>) parent.getItemAtPosition(position);
        Intent intent = (Intent) map.get(TAG_INTENT);
        startActivity(intent);
    }
}

در این اکتیویتی هم اگر تعداد لیست زیاد باشد Scroll Pralax انجام می شود.
حالا وارد فایل اکتیویتی دوم می شویم که نام آن برابر با ParallaxToolbarScrollViewActivity.java است و کدهای زیر را در آن قرار دهید.

package ir.programchi;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
import com.github.ksoichiro.android.observablescrollview.ScrollState;
import com.github.ksoichiro.android.observablescrollview.ScrollUtils;
import com.nineoldandroids.view.ViewHelper;
public class ParallaxToolbarScrollViewActivity extends AppCompatActivity implements ObservableScrollViewCallbacks {
    private View mImageView;
    private View mToolbarView;
    private ObservableScrollView mScrollView;
    private int mParallaxImageHeight;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_parallaxtoolbarscrollview);
        setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
        mImageView = findViewById(R.id.image);
        mToolbarView = findViewById(R.id.toolbar);
        mToolbarView.setBackgroundColor(ScrollUtils.getColorWithAlpha(0, getResources().getColor(R.color.primary)));
        mScrollView = (ObservableScrollView) findViewById(R.id.scroll);
        mScrollView.setScrollViewCallbacks(this);
        mParallaxImageHeight = getResources().getDimensionPixelSize(R.dimen.parallax_image_height);
    }
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        onScrollChanged(mScrollView.getCurrentScrollY(), false, false);
    }
    @Override
    public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
        int baseColor = getResources().getColor(R.color.primary);
        float alpha = Math.min(1, (float) scrollY / mParallaxImageHeight);
        mToolbarView.setBackgroundColor(ScrollUtils.getColorWithAlpha(alpha, baseColor));
        ViewHelper.setTranslationY(mImageView, scrollY / 2);
    }
    @Override
    public void onDownMotionEvent() {
    }
    @Override
    public void onUpOrCancelMotionEvent(ScrollState scrollState) {
    }
}

و در آخر باید در AndroidManifest.xml دو تا اکتیویتی مثل زیر تعریف بشوند (در غیر اینصورت خطا خواهید داشت)

<activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity
            android:name=".ParallaxToolbarScrollViewActivity"
            android:label="@string/title_activity_parallaxtoolbarscrollview"
            android:theme="@style/AppTheme.Toolbar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name=".androidobservablescrollview" />
            </intent-filter>
        </activity>

 
 
این آموزش هم به اتمام رسید هر چند طولانی بود ولی خیلی مطلب در آن هست کافی است برنامه را اجرا کنید تا متوجه شوید.
 
موفق و پیروز باشید.

مطالعه بیشتر