24

के साथ मैं नई डिजाइन सामग्री लाइब्रेरी को समझने के लिए Cheesesquare उदाहरण प्रोजेक्ट का पालन कर रहा हूं।एंड्रॉइड CollapsingToolbarLayout कस्टम व्यू

मुझे आश्चर्य है कि क्या CollapsingToolbarLayout विजेट द्वारा प्रदान किए गए सरल शीर्षक के बजाय छवि दृश्य, शीर्षक और उपशीर्षक के साथ कस्टम दृश्य (जैसे टेलीग्राम) का उपयोग करने का कोई तरीका है।

धन्यवाद।

+0

आप एक 'CollapsingToolbarLayout' की कोशिश की है: उदाहरण के लिए यहाँ एक राय यह है कि एक शीर्षक और एक उपशीर्षक शामिल है जिसमें 'ImageView' पहले और फिर' 'LinearLayout' 2 'टेक्स्ट व्यू के साथ है? – shkschneider

+0

मैंने कोशिश की है, लेकिन मेरा उद्देश्य टूलबार में शीर्षक की एनीमेशन को संरक्षित करने के लिए मेरे कस्टम व्यू के साथ शीर्षक को प्रतिस्थापित करना है। – CeccoCQ

+0

@shkschneider आप थोड़ा और समझाएंगे। मैं –

उत्तर

21

मुझे एक ही समस्या थी और समाधान खोजने की कोशिश करने में कई घंटे बिताए। मेरा समाधान CollapsingToolbarLayout के अंदर ढहने वाले दृश्य (छवि दृश्य और टेक्स्ट व्यू) को जोड़ना था और फिर कोड में संक्रमण को संभालना था। इस तरह यह CollapsingToolbarLayout से विस्तार से अधिक लचीला और सरल है।

सबसे पहले आप लंबन गुणों के साथ CollapsingToolbarLayout के अंदर अपने विचार जोड़ने की आवश्यकता होगी: किसी तरह

private static final float SCALE_MINIMUM=0.5f; 
    appBarLayout.setOnWorkingOffsetChange(new ControllableAppBarLayout.OnWorkingOffsetChange() { 
     @Override 
     public void onOffsetChange(int offSet, float collapseDistance) { 
      imageView.setScaleX(1 + (collapseDistance * SCALE_MINIMUM)); 
      imageView.setScaleY(1 + (collapseDistance * SCALE_MINIMUM)); 

      textView.setScaleX(1 + (collapseDistance * SCALE_MINIMUM)); 
      textView.setScaleY(1 + (collapseDistance * SCALE_MINIMUM)); 

      // You can also setTransitionY/X, setAlpha, setColor etc. 
     } 
    }); 

:

 <ImageView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:paddingTop:"80dp" 
      android:src="@drawable/icon" 
      app:layout_collapseMode="parallax" 
      app:layout_collapseParallaxMultiplier="0.8"/> //set vertical transition here 

फिर एक OnOffsetchangeListner की मदद से दृश्य की स्केलिंग सेट डिफ़ॉल्ट offsetChangedListener मेरे लिए ठीक से काम नहीं करता है (आपको शायद इसे अभी भी डिफ़ॉल्ट श्रोता के साथ आजमाया जाना चाहिए), इसलिए मैंने https://gist.github.com/blipinsk/3f8fb37209de6d3eea99 से ControllableAppBarLayout का उपयोग किया और निम्न को जोड़ा:

private OnWorkingOffsetChange onWorkingOffsetChange; 

@Override 
public void onOffsetChanged(AppBarLayout appBarLayout, int i) { 
    if (!isInEditMode()) { 
     onWorkingOffsetChange.onOffsetChange(i, (float) i/appBarLayout.getTotalScrollRange()); 
    } 
} 

public void setOnWorkingOffsetChange(OnWorkingOffsetChange listener) { 
    this.onWorkingOffsetChange = listener; 
} 

public interface OnWorkingOffsetChange { 
    void onOffsetChange(int offSet, float collapseDistance); 
} 

केवल समस्या यह है कि आप अपने CollapsingToolbarLayout के लिए app:contentScrim="#00000000" (पारदर्शी) सेट करना होगा तो अपने विचार अभी भी दिखाई दे रहे हैं जब उपकरण पट्टी संकुचित हो जाता है, है। यदि आपको वास्तव में ढहने-पृष्ठभूमि प्रभाव की आवश्यकता है तो मुझे यकीन है कि आप OffsetChangeListener में पृष्ठभूमि छवि के दृश्य को अल्फा सेट करके "नकली" कर सकते हैं। ;)

+0

क्या आप कृपया थोड़ा और समझाएंगे। मुझे एक ही समस्या है, मैं सिर्फ 'CollapsingToolBarLayout' के केंद्र में एक आइकन और एक शीर्षक का उपयोग करना चाहता हूं, जब मैं आइकन से ऊपर स्क्रॉल करता हूं तो टूलबार के बाएं तरफ उड़ना चाहिए जहां आम तौर पर ऐप आइकन मौजूद होता है और शीर्षक दाईं ओर होता है आइकन का –

2

विजेट से स्वयं सीधे इसे सक्षम करने का एक तरीका प्रतीत नहीं होता है, जैसे टूलबार में कस्टम दृश्य जोड़ना संभव था।

हालांकि आप क्या करने का प्रयास कर सकते हैं, CollapsingToolbarLayout.class का स्रोत खोलें और देखें कि CollapsingTextHelper.class का शीर्षक शीर्षक सेट करने के लिए कैसे उपयोग किया जाता है। आप CollapsingToolbarLayout से विस्तार करके अपना खुद का विजेट बनाने का प्रयास कर सकते हैं।

ये लिंक कस्टम घटकों/विचारों, बनाने यदि आप उन्हें पहले नहीं बनाया है देकर आपकी सहायता कर सकते हैं: Custom Views, Custom Components

मैं अभी तक इस प्रयास नहीं किया है, लेकिन यह वास्तव में कुछ मैं के बारे में सोच रहा था जैसा कि आप ढूंढ रहे हैं उसी तरह के समाधान को प्राप्त करने की कोशिश कर रहे हैं। कदम मैं tihkn मैं का पालन करेगा, अब तक:

  1. बनाएं कस्टम अपनी खुद की MyCollapsingToolbarLayoutattrs.xml
  2. में उपशीर्षक सेटिंग्स के लिए जिम्मेदार बताते हैं बनाएं मूल एक बढ़ा कर।
  3. रचनाकारों में super पर कॉल करना सुनिश्चित करें, इसलिए मूल घटक बरकरार रहेगा।
  4. अपने घटक में एक नया CollapsingTextHelper जोड़कर subtitleTextHelper बनाएं।
  5. वास्तव में अपने उपशीर्षक को आकर्षित करने के लिए onDraw ओवरराइड करें।
  6. अपने उपशीर्षक विशेषताओं (डिफ़ॉल्ट स्टाइल और ऐसे, शायद एक निश्चित उपशीर्षक पाठ) के साथ अपने CollapingsToolbarLayout युक्त लेआउट अपडेट करें।
  7. Activity में परिवर्तनों को लागू करें जिसमें CollapsingToolbar है। (CollapsingToolbarlayout से MyCollapingsToolbarLayout पर बदलें, उपशीर्षक सेट करें, अतिरिक्त कस्टम सेटिंग्स आदि)।
  8. क्रॉस उंगलियों, परीक्षण।

अब इसे देखने के लिए जा रहे हैं।

+0

का उपयोग करना चाहता हूं यह वास्तव में कड़ी मेहनत थी। CollapsingToolbarLayout एक भयानक विजेट है। – CeccoCQ

+1

@ StingRay5 क्या आप मेरी मदद कर सकते हैं क्या ड्रा() में अंदर क्या करना है? या कृपया अपना कोड साझा करें। – Max

2

कैसे आप पतन पर गायब नहीं करने के लिए अपने कस्टम दृश्य प्राप्त कर सकते हैं दिखाने के लिए निर्मित किशोर का जवाब थोड़ा संपादित करने के लिए जा रहे हैं:

सबसे पहले आप लंबन गुणों के साथ CollapsingToolbarLayout के अंदर अपने विचार जोड़ने की आवश्यकता होगी:

 <ImageView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:paddingTop:"80dp" 
      android:src="@drawable/icon" 
      app:layout_collapseMode="parallax" 
      app:layout_collapseParallaxMultiplier="0.8"/> //set vertical transition here 

इसके बजाय कस्टम दृश्य के प्रोग्राम के रूप में जोड़ सकते हैं और यह पतन पर गायब नहीं होंगे।

final FrameLayout frameLayout = new FrameLayout(mActivity); 
    FrameLayout.LayoutParams frameLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, 
      FrameLayout.LayoutParams.MATCH_PARENT); 
    frameLayout.setLayoutParams(frameLayoutParams); 


    // Create new LinearLayout 
    final LinearLayout linearLayout = new LinearLayout(mActivity); 
    frameLayoutParams =new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, dpToPixels(78)); 
    frameLayoutParams.gravity = Gravity.BOTTOM; 
    linearLayout.setLayoutParams(frameLayoutParams); 
    linearLayout.setOrientation(LinearLayout.VERTICAL); 


    // Add textviews 
    final TextView textView1 = new TextView(mActivity); 
    LinearLayout.LayoutParams linearLayoutParams =new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 
      LinearLayout.LayoutParams.WRAP_CONTENT); 
    frameLayoutParams.gravity = Gravity.BOTTOM; 
    textView1.setLayoutParams(linearLayoutParams); 
    textView1.setText("Title"); 
    textView1.setTextColor(ContextCompat.getColor(mActivity, R.color.colorWhite)); 
    textView1.setTextSize(TypedValue.COMPLEX_UNIT_SP, 40); 
    linearLayout.addView(textView1); 


    final TextView textView2 = new TextView(mActivity); 
    linearLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 
      LinearLayout.LayoutParams.WRAP_CONTENT); 
    textView2.setLayoutParams(linearLayoutParams); 
    textView2.setText("Subtitle"); 
    textView2.setTextColor(ContextCompat.getColor(mActivity, R.color.colorWhite)); 
    textView2.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); 
    linearLayout.addView(textView2); 

    frameLayout.addView(linearLayout); 


    collapsingToolbar.addView(frameLayout); 
    final float SCALE_MIN=0.4f; 
    AppBarLayout appBarLayout = (AppBarLayout) mActivity.findViewById(R.id.appBarLayout); 
    appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { 
     @Override 
     public void onOffsetChanged(AppBarLayout appBarLayout, int offSet) { 
      float collapsedRatio = (float) offSet/appBarLayout.getTotalScrollRange(); 
      linearLayout.setScaleX(1 + (collapsedRatio * SCALE_MIN)); 
      linearLayout.setScaleY(1 + (collapsedRatio * SCALE_MIN)); 
      FrameLayout.LayoutParams frameLayoutParams =new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, dpToPixels(78)); 
      frameLayoutParams.gravity = Gravity.BOTTOM; 
      frameLayoutParams.setMargins(Math.round(dpToPixels(48) * (1+collapsedRatio)), 0, 0, Math.round(dpToPixels(15) * collapsedRatio)); 
      linearLayout.setLayoutParams(frameLayoutParams); 
      // You can also setTransitionY/X, setAlpha, setColor etc. 
     } 
    }); 

/////

float lastCollapsedRatio = -2; 

////

private int dpToPixels(int padding_in_dp){ 
    final float scale = getResources().getDisplayMetrics().density; 
    int padding_in_px = (int) (padding_in_dp * scale + 0.5f); 
    return padding_in_px; 
} 
+0

ग्रेट चाल। सिवाय इसके कि मुझे अचानक निम्नलिखित के साथ मेरे लॉग मिल गए। इससे बचने के तरीके पर कोई विचार? (गाह, एसओ क्यों समर्थन लाइन ब्रेक का समर्थन नहीं कर सकता?) 'requestLayout() को एंड्रॉइड.support.design.widget.CollapsingToolbarLayout {a9c7244 V.ED ..... ...... i द्वारा अनुचित रूप से बुलाया गया है। 0,0-1440,405 # 7f1100fb ऐप: आईडी/collapsingToolbarLayout} लेआउट के दौरान: दूसरा लेआउट पास चल रहा है ' ' requestLayout() अनुचित रूप से android.widget.LinearLayout {4058f2d VE ..... द्वारा बुलाया गया ...... मैं। लेआउट के दौरान 168,132-1440,405}: दूसरे लेआउट पास ' –

+0

चलाते हुए मैंने यह देखने के लिए एक चेक जोड़ा कि क्या' ढह गया 'वास्तव में बदल गया है और केवल उन मामलों में स्केलिंग करें।इससे सभी लेआउट पास गायब होने के बारे में सभी शिकायतें हुईं। –

+0

मैंने थोड़ी देर में इस कोड का उपयोग नहीं किया है। लेकिन मुझे याद आ रहा है कि। आपने चेक कहाँ जोड़ा? मैं अपना जवाब अपडेट कर सकता हूं। @RoySolberg – luca992

संबंधित मुद्दे