অ্যান্ড্রয়েড কলসিংটুলবারলআউট শ্রোতা


106

আমি ব্যবহার করছি CollapsingToolBarLayoutসঙ্গে পাশাপাশি AppBarLayoutএবং CoordinatorLayout, এবং তারা ফাইন পুরাপুরি কাজ করছে। আমি Toolbarযখন স্ক্রোল আপ করেছিলাম তখন আমার সংশোধন করতে সেট করেছিলাম , আমি জানতে চাই যে সরঞ্জামদণ্ডের শিরোনাম পাঠ্যটি CollapsingToolBarLayoutভেঙে যাওয়ার পরে কোনও উপায় আছে কিনা ।

মোড়ানো, আমি দুটি আলাদা শিরোনাম চাই যখন স্ক্রোল করা হবে এবং যখন প্রসারিত হবে

সবাইকে আগাম ধন্যবাদ

উত্তর:


150

আমি @ ফ্রিডিয়ো শুরুগুলি এবং @ নিফেল কোডের উপর ভিত্তি করে সম্পূর্ণ বাস্তবায়নটি ভাগ করেছি:

public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener {

    public enum State {
        EXPANDED,
        COLLAPSED,
        IDLE
    }

    private State mCurrentState = State.IDLE;

    @Override
    public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {
        if (i == 0) {
            if (mCurrentState != State.EXPANDED) {
                onStateChanged(appBarLayout, State.EXPANDED);
            }
            mCurrentState = State.EXPANDED;
        } else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
            if (mCurrentState != State.COLLAPSED) {
                onStateChanged(appBarLayout, State.COLLAPSED);
            }
            mCurrentState = State.COLLAPSED;
        } else {
            if (mCurrentState != State.IDLE) {
                onStateChanged(appBarLayout, State.IDLE);
            }
            mCurrentState = State.IDLE;
        }
    }

    public abstract void onStateChanged(AppBarLayout appBarLayout, State state);
}

এবং তারপরে আপনি এটি ব্যবহার করতে পারেন:

appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
    @Override
    public void onStateChanged(AppBarLayout appBarLayout, State state) {
        Log.d("STATE", state.name());
    }
});

21
এটাই সঠিক. তবে দয়া করে এটি করবেন না যে প্রগার্ডটি ব্যবহার করে যা এনাম একটি পূর্ণসংখ্যার মান অনুবাদ করা হবে।
rciovati

1
আমি এটা জানতাম না। দারুণ!
টিম 687

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

অ্যানড্রয়েড এনামগুলির জন্য @pdpin_sज्ञान ইন্টারডিফ পরীক্ষা করে দেখুন
ডেভিড দারিয়াস


95

এই সমাধানটি AppBarLayoutধসে পড়া বা প্রসারিত সনাক্ত করতে আমার পক্ষে পুরোপুরি কাজ করে ।

appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

            if (Math.abs(verticalOffset)-appBarLayout.getTotalScrollRange() == 0)
            {
                //  Collapsed


            }
            else
            {
                //Expanded


            }
        }
    });

addOnOffsetChangedListenerউপর ব্যবহৃত AppBarLayout


36

একটি হুক OnOffsetChangedListenerআপনার টু AppBarLayout। যখন উচ্চতা verticalOffsetথেকে 0 বা তার চেয়ে কম পৌঁছে যায় Toolbar, এর অর্থ হ'ল কলাপসিংটুলবারলআউটটি ধসে পড়েছে, অন্যথায় এটি প্রসারিত বা প্রসারিত হবে।

mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                if(verticalOffset == 0 || verticalOffset <= mToolbar.getHeight() && !mToolbar.getTitle().equals(mCollapsedTitle)){
                    mCollapsingToolbar.setTitle(mCollapsedTitle);
                }else if(!mToolbar.getTitle().equals(mExpandedTitle)){
                    mCollapsingToolbar.setTitle(mExpandedTitle);
                }

            }
        });

1
এটা আমার জন্য কাজ করে না। অনক্ল্যাপস আমি হোম বোতামটি সক্ষম করতে চাই এবং বাড়ির বোতামটি লুকিয়ে
রাখি

9
টুলবারটি পুরোপুরি প্রসারিত হওয়ার পরে উল্লম্ব অফসেটের মানগুলি শূন্য বলে মনে হয় এবং তার পরে সঙ্কুচিত হওয়ার সময় নেতিবাচক হয়। যখন সরঞ্জামদণ্ডটি সঙ্কুচিত হয়, তখন উল্লম্ব অফসেটটি সরঞ্জামদণ্ডের উচ্চতার (-mToolbar.getHeight ()) নেগেটিভের সমান। সুতরাং ... সরঞ্জামদণ্ডটি আংশিকভাবে প্রসারিত হয়েছে "যদি (উল্লম্ব অফসেট> -মিটুলবার.জিটহাইট ())"
মাইক

appBarLayout.getVerticalOffset()পদ্ধতিটি কোথায় রয়েছে তা যদি কেউ ভাবছেন তবে আপনি appBarLayout.getY()কলব্যাকে ব্যবহৃত একই মানটি পুনরুদ্ধার করতে কল করতে পারেন ।
জেরেট মিল্লার্ড 21

দুর্ভাগ্যক্রমে জেরেট মিলার্ড ঠিক নেই isn't আপনার ফিটসিসটাম উইন্ডো কনফিগারেশন এবং স্ট্যাটাসবার কনফিগারেশনের উপর নির্ভর করে (স্বচ্ছ) appBarLayout.getY()এটি হতে পারেverticalOffset = appBarLayout.getY() + statusBarHeight
মকর রাশি

1
কেউ কি লক্ষ্য করেছে যে আমরা যদি অ্যাপ্লিকেশনটির সাথে আসলে ইন্টারেক্ট করছি না এমনকি mAppBarLayout.addOnOffsetChangedListener (শ্রোতা) কে বারবার বলা হয়? বা এটি আমার লেআউট / অ্যাপ্লিকেশনের একটি বাগ যেখানে আমি এই আচরণটি পর্যবেক্ষণ করছি। Plz সহায়তা!
রাহুল শুক্লা

16

এই কোডটি আমার পক্ষে কাজ করেছিল

mAppBarLayout.addOnOffsetChangedListener(new   AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
            if (verticalOffset == -mCollapsingToolbarLayout.getHeight() + mToolbar.getHeight()) {
                //toolbar is collapsed here
                //write your code here
            }
        }
    });

নিকোলা দেশপোটোস্কির চেয়ে উত্তম উত্তর
বালা

একটি নির্ভরযোগ্য সমাধান বলে মনে হচ্ছে না। তবে -693 সমান mCollapsingToolbarLayout.getHeight () = 1013, mToolbar.getHeight () 224. = সুতরাং ধসে পড়া রাজ্যের আপনার সমাধান verticalOffset অনুযায়ী -789 হতে হবে,: আমি এটা আমার ডিভাইসে মান অনুসরণ করছে পরীক্ষিত
লিও ড্রডকোডার

16
private enum State {
    EXPANDED,
    COLLAPSED,
    IDLE
}

private void initViews() {
    final String TAG = "AppBarTest";
    final AppBarLayout mAppBarLayout = findViewById(R.id.appbar);
    mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
        private State state;

        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
            if (verticalOffset == 0) {
                if (state != State.EXPANDED) {
                    Log.d(TAG,"Expanded");
                }
                state = State.EXPANDED;
            } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) {
                if (state != State.COLLAPSED) {
                    Log.d(TAG,"Collapsed");
                }
                state = State.COLLAPSED;
            } else {
                if (state != State.IDLE) {
                    Log.d(TAG,"Idle");
                }
                state = State.IDLE;
            }
        }
    });
}

10

আপনি নীচে ব্যবহার করে টুলবার আলফা শতাংশ ভাগ করতে পারেন:

appbarLayout.addOnOffsetChangedListener( new AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
            float percentage = ((float)Math.abs(verticalOffset)/appBarLayout.getTotalScrollRange());
            fadedView.setAlpha(percentage);
    });

রেফারেন্সের জন্য: লিঙ্ক


2
এটি একটি সাধারণ উত্তর হিসাবে এটি একটি সাধারণীকৃত অফসেট দেয়। আমার মতে, API এর verticalOffsetপিক্সেল দূরত্বের পরিবর্তে এটি সরাসরি সরবরাহ করা উচিত ছিল ।
dbm

5

এখানে একটি কোটলিন সমাধান। একটিতে যুক্ত OnOffsetChangedListenerকরুন AppBarLayout

পদ্ধতি এ:

যোগ AppBarStateChangeListener.ktআপনার প্রকল্পে:

import com.google.android.material.appbar.AppBarLayout
import kotlin.math.abs

abstract class AppBarStateChangeListener : AppBarLayout.OnOffsetChangedListener {

    enum class State {
        EXPANDED, COLLAPSED, IDLE
    }

    private var mCurrentState = State.IDLE

    override fun onOffsetChanged(appBarLayout: AppBarLayout, i: Int) {
        if (i == 0 && mCurrentState != State.EXPANDED) {
            onStateChanged(appBarLayout, State.EXPANDED)
            mCurrentState = State.EXPANDED
        }
        else if (abs(i) >= appBarLayout.totalScrollRange && mCurrentState != State.COLLAPSED) {
            onStateChanged(appBarLayout, State.COLLAPSED)
            mCurrentState = State.COLLAPSED
        }
        else if (mCurrentState != State.IDLE) {
            onStateChanged(appBarLayout, State.IDLE)
            mCurrentState = State.IDLE
        }
    }

    abstract fun onStateChanged(
        appBarLayout: AppBarLayout?,
        state: State?
    )

}

শ্রোতাদের আপনার যোগ করুন appBarLayout:

appBarLayout.addOnOffsetChangedListener(object: AppBarStateChangeListener() {
        override fun onStateChanged(appBarLayout: AppBarLayout?, state: State?) {
            Log.d("State", state.name)
            when(state) {
                State.COLLAPSED -> { /* Do something */ }
                State.EXPANDED -> { /* Do something */ }
                State.IDLE -> { /* Do something */ }
            }
        }
    }
)

পদ্ধতি বি:

appBarLayout.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
        if (abs(verticalOffset) - appBarLayout.totalScrollRange == 0) { 
            // Collapsed
        } else if (verticalOffset == 0) {
            // Expanded
        } else {
            // Idle
        }
    }
)

3

এই সমাধানটি আমার পক্ষে কাজ করছে:

@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
  if (i == 0) {
    if (onStateChangeListener != null && state != State.EXPANDED) {
      onStateChangeListener.onStateChange(State.EXPANDED);
    }
    state = State.EXPANDED;
  } else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
    if (onStateChangeListener != null && state != State.COLLAPSED) {
      onStateChangeListener.onStateChange(State.COLLAPSED);
    }
    state = State.COLLAPSED;
  } else {
    if (onStateChangeListener != null && state != State.IDLE) {
      onStateChangeListener.onStateChange(State.IDLE);
    }
    state = State.IDLE;
  }
}

অ্যাপবারআলআউটে অ্যাডঅনঅফসেটচ্যাঞ্জডলিস্টনার ব্যবহার করুন।


আপনি কি আপনার সম্পূর্ণ কোডটি ভাগ করতে পারেন? স্টেট। এক্সপেন্ডেড ইত্যাদি কী?
চেতনা

1

আপনি যদি কলসিংটুলবারলআউট ব্যবহার করছেন তবে আপনি এটি রাখতে পারেন

collapsingToolbar.setExpandedTitleColor(ContextCompat.getColor(activity, android.R.color.transparent));
collapsingToolbar.setTitle(title);

1

এই কোডটি আমার জন্য নিখুঁতভাবে কাজ করছে। আপনি কীভাবে চান তা শতাংশ স্কেল ব্যবহার করতে পারেন

@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
    double percentage = (double) Math.abs(verticalOffset) / collapsingToolbar.getHeight();
    if (percentage > 0.8) {
        collapsingToolbar.setTitle("Collapsed");
    } else {
        collapsingToolbar.setTitle("Expanded");
    }
}

0

আমার সরঞ্জামদণ্ডের অফসেট মান -582 যখন ধসে পড়বে, প্রসারিত হবে = 0 তে তাই আমি টোস্টে অফসেটু সেট করে সেই অনুযায়ী কোড পরিবর্তন করে মান খুঁজে পাই।

 mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
            if(verticalOffset == -582) {
            Toast.makeText(MainActivity.this, "collaped" + verticalOffset, Toast.LENGTH_SHORT).show();
            mCollapsingToolbarLayout.setTitle("Collapsed");
            }else if(verticalOffset == 0){
                Toast.makeText(MainActivity.this, "expanded" + verticalOffset, Toast.LENGTH_SHORT).show();
            mCollapsingToolbarLayout.setTitle("expanded");
            }
        }
    });
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.