অ্যান্ড্রয়েড: আমি ভিউপ্যাজার Wrap_CONTENT রাখতে অক্ষম


258

আমি একটি সাধারণ ভিউপেজার সেটআপ করেছি যার প্রতি পৃষ্ঠায় 200dp উচ্চতা সহ একটি চিত্র ভিউ রয়েছে।

এখানে আমার পেজার:

pager = new ViewPager(this);
pager.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
pager.setBackgroundColor(Color.WHITE);
pager.setOnPageChangeListener(listener);
layout.addView(pager);

উচ্চতাটিকে মোড়ক_সামগ্রী হিসাবে সেট করা সত্ত্বেও, চিত্রগ্রাহকটি কেবল 200dp থাকা সত্ত্বেও পেজার সর্বদা স্ক্রিনটি পূরণ করে। আমি পেজারের উচ্চতা "200" দিয়ে প্রতিস্থাপন করার চেষ্টা করেছি তবে এটি আমাকে একাধিক রেজোলিউশনের মাধ্যমে বিভিন্ন ফলাফল দেয়। আমি সেই মানটিতে "dp" যুক্ত করতে অক্ষম। পেজারের বিন্যাসে আমি কীভাবে 200 ডিপি যুক্ত করব?


1
দয়া করে ইস্যু কোড. google.com/p/android/issues/detail?id=54604
খ্রিস্ট

উত্তর:


408

ViewPagerনিম্নলিখিত হিসাবে আপনার অ্যাকাউন্টের ওভাররাইডিং এটি বর্তমানে এটি সবচেয়ে বড় সন্তানের উচ্চতা অর্জন করবে।

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    int height = 0;
    for(int i = 0; i < getChildCount(); i++) {
        View child = getChildAt(i);
        child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        int h = child.getMeasuredHeight();
        if(h > height) height = h;
    }

    if (height != 0) {
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
    }

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

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

3
এখানে একটি ছোট সমস্যা রয়েছে যা আমি ঠিক করতে যাচ্ছি: যদি ভিউপ্যাজারের এর দৃশ্যমানতাটি GONE এ থাকে এবং আপনি এটি দৃশ্যমান হিসাবে সেট করেন তবে onMeasure এর খণ্ডটি তৈরি হওয়ার আগেই কল হয়ে যায়। সুতরাং এটি 0 এর উচ্চতা সমাপ্ত হবে anyone কারও যদি ধারণা থাকে তবে সে স্বাগত। আমি মনে করি যখন খণ্ডটি তৈরি হবে তখন আমি কলব্যাক নিয়ে যাব
এডোয়ার্ডোটোগনি

4
আপনার সাজসজ্জার শিশু দৃষ্টিভঙ্গি থাকলে এটি কাজ করবে না - এর কারণ ViewPager.onMeasure () সজ্জা মতামতগুলি পরিমাপ করে এবং প্রথমে তাদের জন্য স্থান বরাদ্দ করে, তারপরে বাকী স্থানটি অ-সজ্জা শিশুদের দেয়। তা সত্ত্বেও, এটি এখানের সর্বনিম্ন ভুল সমাধানটি তাই আমি উত্সাহিত করেছি;)
বেনজমিন ডাবেল

3
আমি যখনই
ভিউপ্যাজারটি

7
আপনি ইতিমধ্যে ভিউপিজারে সেটএডাপ্টার () সম্পাদন করার সময় getChildCount () 0 ফিরে আসতে পারে! প্রকৃত পপুলেট () কলটি (যা দৃষ্টিভঙ্গি তৈরি করে) সুপার.অনম্যাসার্সের (প্রস্থমাপচারস্পেক, উচ্চতামাপ স্পেস) এর অভ্যন্তরে ঘটে; কল করুন। এই ফাংশনটি শুরু করার সময় অতিরিক্ত সুপার.অনম্যাসার () কলটি করা কৌতুকটি করেছিল। এছাড়াও পরীক্ষা stackoverflow.com/questions/38492210/...
southerton

106

আর একটি জেনেরিক সমাধান হ'ল wrap_contentসবেমাত্র কাজ করা।

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

আপনি এই ভিউপাগারটি মূল ভিউপ্যাজারের মতোই আপনার এক্সএমএল লেআউটে ব্যবহার করতে পারেন:

<view
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    class="de.cybergen.ui.layout.WrapContentHeightViewPager"
    android:id="@+id/wrapContentHeightViewPager"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"/>

সুবিধা: এই পদ্ধতিটি অন্যান্য ইউআই উপাদানগুলিকে ওভারলে করতে রিলেটিভলআউট সহ যে কোনও বিন্যাসে ভিউপেজার ব্যবহারের অনুমতি দেয়।

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

কোডটি এখানে:

public class WrapContentHeightViewPager extends ViewPager {

    /**
     * Constructor
     *
     * @param context the context
     */
    public WrapContentHeightViewPager(Context context) {
        super(context);
    }

    /**
     * Constructor
     *
     * @param context the context
     * @param attrs the attribute set
     */
    public WrapContentHeightViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // find the first child view
        View view = getChildAt(0);
        if (view != null) {
            // measure the first child view with the specified measure spec
            view.measure(widthMeasureSpec, heightMeasureSpec);
        }

        setMeasuredDimension(getMeasuredWidth(), measureHeight(heightMeasureSpec, view));
    }

    /**
     * Determines the height of this view
     *
     * @param measureSpec A measureSpec packed into an int
     * @param view the base view with already measured height
     *
     * @return The height of the view, honoring constraints from measureSpec
     */
    private int measureHeight(int measureSpec, View view) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            // set the height from the base view if available
            if (view != null) {
                result = view.getMeasuredHeight();
            }
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

}

34
ভিউপ্যাজারটি ধ্বংস করে আবার খুললে অন্য কারও কাছে বর্তমান আইটেমটির পাশে ফাঁকা পৃষ্ঠা পাওয়া গেল?
Zyoo

1
আমিও ফাঁকা পাতা পেয়েছি।
আয়ারেন

10
আমার ব্লগে বর্ণিত হিসাবে আপনাকে কেবল এই প্রশ্নের দুটি শীর্ষ উত্তর একত্রিত করতে হবে: pristalovpavel.wordpress.com/2014/12/26/…
anil

4
'ড্যানিয়েল ল্যাপেজ লাকাল্লে' দিয়ে দেওয়া উত্তরের সাথে কেবল 'অনম্যাসার' পদ্ধতির কোডটি প্রতিস্থাপন করুন।
যোগ গুরু

1
গ্রেট ..! আমার জন্য কাজ করেছেন .. @ সাইবারজেন অনেক ধন্যবাদ আপনি আমার দিনটি বাঁচিয়েছিলেন ..!
জ্ঞানেশ এম

59

আমি আমার উত্তর ড্যানিয়েল ল্যাপেজ লাকাল এবং এই পোস্টের উপর ভিত্তি করে রেখেছি http://www.henning.ms/2013/09/09/viewpager-that-simply-dont-measure-up/ । ড্যানিয়েলের উত্তরের সমস্যাটি হ'ল কিছু ক্ষেত্রে আমার বাচ্চাদের উচ্চতা শূন্য ছিল। সমাধানটি ছিল দুর্ভাগ্যক্রমে দুবার পরিমাপ করা।

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int mode = MeasureSpec.getMode(heightMeasureSpec);
    // Unspecified means that the ViewPager is in a ScrollView WRAP_CONTENT.
    // At Most means that the ViewPager is not in a ScrollView WRAP_CONTENT.
    if (mode == MeasureSpec.UNSPECIFIED || mode == MeasureSpec.AT_MOST) {
        // super has to be called in the beginning so the child views can be initialized.
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int height = 0;
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if (h > height) height = h;
        }
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
    }
    // super has to be called again so the new specs are treated as exact measurements
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

আপনি চাইলে বা কেবল মোড়ানো_ কনটেন্টটি চাইলে এটি আপনাকে ভিউপাগারে একটি উচ্চতা সেট করতে দেয়।


আমি একই সমস্যা ছিল এবং আপনার উত্তর দিয়ে সমাধান করেছি, ধন্যবাদ। তবে এ সম্পর্কে কোনও ব্যাখ্যা কেন?
বার্ট বার্গ

আমি মনে করি যে তারা মোড়ানো বিষয়বস্তু সমর্থন করার ইচ্ছা পোষণ করেনি কারণ আমি মনে করি না যে তারা ভাবেন যে এটি একটি সাধারণ ব্যবহারের ঘটনা। এটি সমর্থন করার জন্য আমাদের বাচ্চাদের পরিমাপ করার পরে আমাদের নিজেরাই পুনরায় পরিমাপ করতে হবে যাতে আমরা সামগ্রী মোড়ানো করতে পারি।
মিনসম্যান

কেন এই ViewPager চিত্র একটি ImageView একই ব্যবহার করে মধ্যে তুলনায় actualy খাটো scaleTypeএবং একইভাবে, layout_width=match_parentসেইসাথে layout_height=wrap_content? সেখানে 20dp অনুপস্থিত।
হাঙ্গর

হাঙ্গর, আমি সত্যিই নিশ্চিত নই। আপনার স্কেল টাইপটি আসলে কী করছে তার সাথে এর কিছু করার থাকতে পারে। একটি উচ্চতা সেট করার চেষ্টা করতে পারে।
MinceMan

1
আমি ফ্রিকিনকে বিশ্বাস করতে পারি না! আমি আমার কাস্টম ভিউপ্যাজারটি একসাথে 2 দিন আটকিয়ে কাটিয়েছি এবং কোনও সমস্যায় আটকে গিয়েছি, যখন আমার প্রাথমিক দৃষ্টিভঙ্গিটি প্রদর্শিত হবে না এবং আমি কেন বুঝতে পারি না! // super has to be called in the beginning so the child views can be initialized.<----- এ কারণ ছিল, এটি শুরুতে এবং onMeasure ফাংশনের শেষে কল করতে হয়েছিল। ইপিপি, আজ ভার্চুয়াল হাই ফাইভ্স!
স্টারওয়েভ

37

আমি এই সম্পর্কে একটি খুব অনুরূপ প্রশ্নের উত্তর দিচ্ছিলাম, এবং আমার দাবির ব্যাক আপ করার জন্য একটি লিঙ্ক সন্ধান করার সময় এটি খুঁজে পেয়েছিলাম, তাই আপনি ভাগ্যবান :)

আমার অন্য উত্তর:
ভিউপ্যাজারটি সমর্থন করে না wrap_contentকারণ এটি (সাধারণত) তার সমস্ত বাচ্চাদের একই সাথে কখনও বোঝাই করে না এবং তাই উপযুক্ত আকারটি পেতে পারে না (বিকল্পটি এমন একটি পেজার থাকতে হবে যা আপনি যখনই পরিবর্তন করেছেন তখন আকার পরিবর্তন করে) পৃষ্ঠা)।

আপনি তবে একটি সুনির্দিষ্ট মাত্রা সেট করতে পারেন (উদাহরণস্বরূপ 150 ডিপি) এবং match_parentপাশাপাশি কাজ করে।
এছাড়াও আপনি পরিবর্তন করে আপনার কোড থেকে পরিবর্তনশীল মাত্রা পরিবর্তন করতে পারেন heightতার মধ্যে -attribute LayoutParams

আপনার প্রয়োজনের জন্য আপনি তার নিজস্ব এক্সএমএল-ফাইলে ভিউপেজার তৈরি করতে পারেন, 200_p লেআউট_উইট সেট করে এবং তারপরে আপনার কোডে, স্ক্র্যাচ থেকে নতুন ভিউপেজার তৈরি না করে আপনি সেই এক্সএমএল-ফাইলটি স্ফীত করতে পারেন:

LayoutInflater inflater = context.getLayoutInflater();
inflater.inflate(R.layout.viewpagerxml, layout, true);

3
উত্তম উত্তর, ধরণের বিরক্তিকর যে ডিফল্ট আচরণটি "কিছুটা বোধগম্য কিছু করুন।" ব্যাখ্যার জন্য ধন্যবাদ.
ক্রিস ভান্ডেভেল্ডে

8
@ ক্রিস্ভান্ডেভেল্ডে এটি কিছু অ্যান্ড্রয়েড লাইব্রেরির সাধারণ ভাড়াটে বলে মনে হয়।
তাত্ক্ষণিক

1
তবে @ জাভে, ভিউপ্যাজারটি তার বাচ্চাদের বোঝাই করার সময় কেন তার উচ্চতা সামঞ্জস্য করতে পারে না?
Diffy

@ সিকিউএম সত্যই! ভিউপিজারআইডিকেটর লাইব্রেরিতে layout_heightসেট করার ক্ষেত্রে একই সমস্যা রয়েছে wrap_content, তবে এটি নির্দিষ্ট পরিমাণে সেট আপ করার সহজ কাজটি কার্যকর না হওয়ায় এটি আরও খারাপ।
জিউলিও পিয়ানোস্টেলি

20

ড্যানিয়েল ল্যাপেজ লোকাল উত্তরটি ব্যবহার করে , আমি এই ক্লাসটি কোটলিনে তৈরি করেছি। আশা করি এটি আপনার আরও সময় সাশ্রয় করবে

class DynamicHeightViewPager @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : ViewPager(context, attrs) {

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    var heightMeasureSpec = heightMeasureSpec

    var height = 0
    for (i in 0 until childCount) {
        val child = getChildAt(i)
        child.measure(widthMeasureSpec, View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED))
        val h = child.measuredHeight
        if (h > height) height = h
    }

    if (height != 0) {
        heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)
    }

    super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}}

16

আমি ইতিমধ্যে বেশ কয়েকটি প্রকল্পে এই সমস্যার মুখোমুখি হয়েছি এবং কখনও কখনও এর সম্পূর্ণ সমাধান হয়নি। সুতরাং আমি ভিউপ্যাজারের জন্য স্থান-প্রতিস্থাপন হিসাবে একটি র‌্যাপকন্টেন্টভিউ পেজার গিথুব প্রকল্পটি তৈরি করেছি।

https://github.com/rnevet/WCViewPager

সমাধানটি এখানে কয়েকটি উত্তর দ্বারা অনুপ্রাণিত হয়েছিল, তবে উন্নতি করে:

  • স্ক্রোল করার সময় সহ বর্তমান ভিউ অনুযায়ী গতিশীলভাবে ভিউপিজার উচ্চতা পরিবর্তন করে।
  • পেজারট্যাবস্ট্রিপের মতো "সজ্জা" দর্শনগুলির উচ্চতা বিবেচনা করে।
  • সমস্ত প্যাডিং বিবেচনা করে।

সমর্থন লাইব্রেরি সংস্করণ 24 এর জন্য আপডেট হয়েছে যা পূর্ববর্তী বাস্তবায়নটিকে ভেঙে দেয়।


@ এমভাই আপনি কি কোনও সমস্যা খুলতে পারবেন, বা এটি কাঁটাচামচ করতে পারবেন এবং নমুনা অ্যাপটি সংশোধন করতে পারবেন?
রাণন

1
আমি জানতে পেরেছিলাম যে রিসাইক্লারভিউতে কিছু মোড়ানো_ সামগ্রী রয়েছে; যদি আপনি চান একটি কাস্টম LinearLayoutManager ব্যবহার করেন, এটি কাজ করে এই । সুতরাং আপনার লাইব্রেরিতে কোনও ভুল নেই।
নটারিও

1
এখনও যা স্থির করতে হবে তা হ'ল ফ্রেগমেন্টস্টেটপেজারএডাপ্টারের সাথে এর ব্যবহার। দেখে মনে হচ্ছে টুকরো টুকরো টুকরো করার আগে এটি শিশুদের পরিমাপ করছে, এভাবে ছোট উচ্চতা দেয়। আমার জন্য যা কাজ করেছে তা হ'ল লগনের জবাব, যদিও আমি এখনও এটিতে কাজ করছি। আপনি হয়তো আপনার লাইব্রেরিতে সেই পদ্ধতির একত্রিত করার চেষ্টা করতে পারেন। আমি গিথুবের সাথে পরিচিত নই, দুঃখিত।
নটারিও

ধন্যবাদ, আমি এটি একবার দেখে নেব
রায়ানান

1
ফ্রেগমেন্টপেজারএডাপ্টার দিয়ে কীভাবে এই কাজটি করা যায় সে সম্পর্কে যে কেউ ভাবছেন, আপনার অ্যাডাপ্টারটি অভ্যন্তরীণভাবে খণ্ডগুলির একটি তালিকা রেখে অবজেক্টএটপজিশন ইন্টারফেসটি বাস্তবায়ন করুন, যাতে এটি getObjectAtPosition পদ্ধতি থেকে সংশ্লিষ্ট খণ্ডটি ফিরিয়ে আনতে পারে।
পাবলো 21

15

আমি ঠিক একই ইস্যুতে ঝাঁপিয়ে পড়েছি। আমার একটি ভিউপেজার ছিল এবং আমি এটির বোতামে একটি বিজ্ঞাপন প্রদর্শন করতে চাই। আমি যে সমাধানটি পেয়েছি তা হ'ল পেজারটিকে একটি রিলেটিভভিউতে নিয়ে যাওয়া এবং এটির লেআউট_ উপরে নীচে দেখতে চাই এমন আইডিটিতে সেট করা। যে আমার জন্য কাজ করে।

এখানে আমার লেআউটটি এক্সএমএল:

  <RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:id="@+id/AdLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="vertical" >
    </LinearLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/mainpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/AdLayout" >
    </android.support.v4.view.ViewPager>
</RelativeLayout>

4
কেবলমাত্র রেফারেন্সের জন্য আপনার xMLns দরকার নেই: অ্যান্ড্রয়েড = " স্কিমাস.অ্যান্ড্রয়েড. com/apk/res/android " উভয় ক্ষেত্রেই কেবল প্রথম একটিতে।
মার্টিন মার্কনকিনি

2
আপনার সমস্যাটি মোটেও এক রকম ছিল না। আপনার লেআউটটি ভিউপ্যাজারটি ম্যাচ_প্যারেন্টে সেট করে ঠিকঠাক কাজ করে - ওপিতে এমন একটি পরিস্থিতি হয়েছিল যেখানে তিনি চেয়েছিলেন ভিউপাগারটি এর বিষয়বস্তুগুলিতে মোড়া করতে পারে।
k2col

9

আমিও এই সমস্যায় পড়েছিলাম, তবে আমার ক্ষেত্রে আমার একটি FragmentPagerAdapterছিল ViewPagerযা এর পৃষ্ঠাগুলি সরবরাহ করছিল । সমস্যা আমার কাছে তা থাকত ছিল onMeasure()এর ViewPagerআগে কোন নাম ছিল Fragmentsনির্মিত হয়েছে (এবং পারা না আকার নিজেই সঠিকভাবে)।

কিছুটা পরীক্ষা এবং ত্রুটির পরে, আমি দেখতে পেলাম যে finishUpdate()ফ্রেগমেন্টপাগারএডাপ্টারের পদ্ধতিটি Fragmentsপ্রাথমিকভাবে (পরে থেকে ) instantiateItem()শুরু করার FragmentPagerAdapterপরে এবং পৃষ্ঠার স্ক্রোলিংয়ের পরে / পরে ডাকা হবে । আমি একটি ছোট ইন্টারফেস তৈরি করেছি:

public interface AdapterFinishUpdateCallbacks
{
    void onFinishUpdate();
}

যা আমি আমার মধ্যে FragmentPagerAdapterকল এবং কল:

@Override
public void finishUpdate(ViewGroup container)
{
    super.finishUpdate(container);

    if (this.listener != null)
    {
        this.listener.onFinishUpdate();
    }
}

যার ফলে আমাকে setVariableHeight()আমার CustomViewPagerপ্রয়োগের দিকে আহ্বান জানায় :

public void setVariableHeight()
{
    // super.measure() calls finishUpdate() in adapter, so need this to stop infinite loop
    if (!this.isSettingHeight)
    {
        this.isSettingHeight = true;

        int maxChildHeight = 0;
        int widthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY);
        for (int i = 0; i < getChildCount(); i++)
        {
            View child = getChildAt(i);
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.UNSPECIFIED));
            maxChildHeight = child.getMeasuredHeight() > maxChildHeight ? child.getMeasuredHeight() : maxChildHeight;
        }

        int height = maxChildHeight + getPaddingTop() + getPaddingBottom();
        int heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.measure(widthMeasureSpec, heightMeasureSpec);
        requestLayout();

        this.isSettingHeight = false;
    }
}

আমি নিশ্চিত নই যে এটি সর্বোত্তম পন্থা, মন্তব্যগুলি ভাল লাগবে যদি আপনি এটি ভাল / খারাপ / মন্দ বলে মনে করেন তবে আমার প্রয়োগে এটি বেশ ভালভাবে কাজ করছে বলে মনে হয় :)

আশা করছি এটা ওখানে কাওকে সাহায্য করবে!

সম্পাদনা:requestLayout() কল করার পরে আমি যুক্ত করতে ভুলে গেছি super.measure()(অন্যথায় এটি ভিউটি পুনরায় আঁকবে না)।

আমি পিতামাতার প্যাডিং চূড়ান্ত উচ্চতায় যুক্ত করতে ভুলেও গিয়েছি।

আমি মূল প্রস্থ / উচ্চতা মেজারস্পেসগুলি প্রয়োজনীয় হিসাবে একটি নতুন তৈরির পক্ষে রেখেছি। সেই অনুযায়ী কোড আপডেট করেছেন।

আমার আর একটি সমস্যা ছিল যে এটি একটিতে নিজের আকারটি সঠিকভাবে তৈরি করবে না ScrollViewএবং খুঁজে পেল যে অপরাধী তার MeasureSpec.EXACTLYপরিবর্তে শিশুটিকে মাপছে MeasureSpec.UNSPECIFIED। এটি প্রতিফলিত আপডেট।

এই পরিবর্তনগুলি সমস্ত কোডে যুক্ত করা হয়েছে। আপনি চাইলে পুরানো (ভুল) সংস্করণগুলি দেখতে ইতিহাসটি পরীক্ষা করতে পারেন।


আপনি কোডটিতে যা ভুলে গেছেন তাদের কেন আপনি যুক্ত করবেন না দয়া করে।
হাসান

@ হাসান আমি ইতিমধ্যে করেছি, কোনও বিভ্রান্তির জন্য দুঃখিত! উত্তরটি আপডেট করার পাশাপাশি
তাও

অসাধারণ! খুশী হ'ল :)
লগান

8

আর একটি সমাধান হ'ল ViewPagerএর বর্তমান পৃষ্ঠার উচ্চতা অনুযায়ী উচ্চতা আপডেট করা PagerAdapter। ধরে নিচ্ছেন যে আপনি আপনার ViewPagerপৃষ্ঠাগুলি এভাবে তৈরি করছেন :

@Override
public Object instantiateItem(ViewGroup container, int position) {
  PageInfo item = mPages.get(position);
  item.mImageView = new CustomImageView(container.getContext());
  item.mImageView.setImageDrawable(item.mDrawable);
  container.addView(item.mImageView, 0);
  return item;
}

কাঠামোর mPagesঅভ্যন্তরীণ তালিকাটি যেখানে PageInfoগতিশীলভাবে যুক্ত হয়েছে PagerAdapterএবং ওভারডেন পদ্ধতিতে CustomImageViewএটি নিয়মিত ImageViewযা onMeasure()নির্দিষ্ট প্রস্থ অনুযায়ী তার উচ্চতা নির্ধারণ করে এবং চিত্রের অনুপাত অনুপাত রাখে।

আপনি পদ্ধতিতে ViewPagerউচ্চতা জোর করতে পারেন setPrimaryItem():

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
  super.setPrimaryItem(container, position, object);

  PageInfo item = (PageInfo) object;
  ViewPager pager = (ViewPager) container;
  int width = item.mImageView.getMeasuredWidth();
  int height = item.mImageView.getMeasuredHeight();
  pager.setLayoutParams(new FrameLayout.LayoutParams(width, Math.max(height, 1)));
}

নোট করুন Math.max(height, 1)ViewPagerএটি পূর্ববর্তী পৃষ্ঠায় শূন্যের উচ্চতা (অর্থাত্ নাল ড্রয়যোগ্য CustomImageView) হলে দুটি পৃষ্ঠার মাঝে পিছনে পিছনে প্রতিটি বিরল সোয়াইপ থাকে, এমন প্রদর্শিত বিরক্তিকর বাগ সংশোধন করা পৃষ্ঠা (এটি ফাঁকা দেখায়) আপডেট করে না ।


এটি আমার অনুসরণ করার সঠিক পথ বলে মনে হচ্ছে তবে পদ্ধতিগুলির item.mImageView.measure(..)সঠিক মাত্রা পেতে আমার একটি বিজ্ঞাপন দরকার getMeasuredXXX()
জিয়ানলুকা পি।

6

ভিউপ্যাজারের অভ্যন্তরে স্থির সামগ্রী ব্যবহার করার সময় এবং কোনও অভিনব অ্যানিমেশন চাইলে আপনি নিম্নলিখিত ভিউ পেজারটি ব্যবহার করতে পারেন

public class HeightWrappingViewPager extends ViewPager {

  public HeightWrappingViewPager(Context context) {
    super(context);
  }

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

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)   {
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
      View firstChild = getChildAt(0);
      firstChild.measure(widthMeasureSpec, heightMeasureSpec);
      super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(firstChild.getMeasuredHeight(), MeasureSpec.EXACTLY));
  }
}

এটি কাজ করে। আমি বাচ্চাদের মধ্য দিয়ে লুপিং করে এবং একটিকে সর্বোচ্চ উচ্চতায় নিয়ে বাড়িয়েছি।
জাভিয়ের মেন্ডোনিয়া

এমনকি পুনর্ব্যবহারযোগ্য দৃশ্যের অধীনে সূক্ষ্মভাবে কাজ করে
কনডু

আমি এই ব্যতিক্রমটি পাচ্ছি- java.lang.
নালপয়েন্টার এক্সেপশন:

তবে প্রথম উপাদানটি গ্রহণ করা ভুল হতে পারে।
টোবিয়াস রেইচ

4
public CustomPager (Context context) {
    super(context);
}

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

int getMeasureExactly(View child, int widthMeasureSpec) {
    child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
    int height = child.getMeasuredHeight();
    return MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
}

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST;

    final View tab = getChildAt(0);
    if (tab == null) {
        return;
    }

    int width = getMeasuredWidth();
    if (wrapHeight) {
        // Keep the current measured width.
        widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
    }
    Fragment fragment = ((Fragment) getAdapter().instantiateItem(this, getCurrentItem()));
    heightMeasureSpec = getMeasureExactly(fragment.getView(), widthMeasureSpec);

    //Log.i(Constants.TAG, "item :" + getCurrentItem() + "|height" + heightMeasureSpec);
    // super has to be called again so the new specs are treated as
    // exact measurements.
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

4

পপকর্ন সময়ের অ্যান্ড্রয়েড অ্যাপের উত্স কোড থেকে আমি এই সমাধানটি পেয়েছি যা বর্তমান শিশুর আকারের উপর নির্ভর করে দুর্দান্ত অ্যানিমেশন সহ ভিউপিজারের আকারকে গতিশীলভাবে সামঞ্জস্য করে।

https://git.popcorntime.io/popcorntime/android/blob/5934f8d0c8fed39af213af4512272d12d2efb6a6/mobile/src/main/java/pct/droid/widget/WrappingViewPager.java

public class WrappingViewPager extends ViewPager {

    private Boolean mAnimStarted = false;

    public WrappingViewPager(Context context) {
        super(context);
    }

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

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        if(!mAnimStarted && null != getAdapter()) {
            int height = 0;
            View child = ((FragmentPagerAdapter) getAdapter()).getItem(getCurrentItem()).getView();
            if (child != null) {
                child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
                height = child.getMeasuredHeight();
                if (VersionUtils.isJellyBean() && height < getMinimumHeight()) {
                    height = getMinimumHeight();
                }
            }

            // Not the best place to put this animation, but it works pretty good.
            int newHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
            if (getLayoutParams().height != 0 && heightMeasureSpec != newHeight) {
                    final int targetHeight = height;
                    final int currentHeight = getLayoutParams().height;
                    final int heightChange = targetHeight - currentHeight;

                    Animation a = new Animation() {
                        @Override
                        protected void applyTransformation(float interpolatedTime, Transformation t) {
                            if (interpolatedTime >= 1) {
                                getLayoutParams().height = targetHeight;
                            } else {
                                int stepHeight = (int) (heightChange * interpolatedTime);
                                getLayoutParams().height = currentHeight + stepHeight;
                            }
                            requestLayout();
                        }

                        @Override
                        public boolean willChangeBounds() {
                            return true;
                        }
                    };

                    a.setAnimationListener(new Animation.AnimationListener() {
                        @Override
                        public void onAnimationStart(Animation animation) {
                            mAnimStarted = true;
                        }

                        @Override
                        public void onAnimationEnd(Animation animation) {
                            mAnimStarted = false;
                        }

                        @Override
                        public void onAnimationRepeat(Animation animation) {
                        }
                    });

                    a.setDuration(1000);
                    startAnimation(a);
                    mAnimStarted = true;
            } else {
                heightMeasureSpec = newHeight;
            }
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

4

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

অ্যান্ড্রয়েড: মিনিট হাইট ফ্ল্যাগটিও সমর্থিত।

public class ChildWrappingAdjustableViewPager extends ViewPager {
    List<Integer> childHeights = new ArrayList<>(getChildCount());
    int minHeight = 0;
    int currentPos = 0;

    public ChildWrappingAdjustableViewPager(@NonNull Context context) {
        super(context);
        setOnPageChangeListener();
    }

    public ChildWrappingAdjustableViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        obtainMinHeightAttribute(context, attrs);
        setOnPageChangeListener();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {            
        childHeights.clear();

        //calculate child views
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if (h < minHeight) {
                h = minHeight;
            }
            childHeights.add(i, h);
        }

        if (childHeights.size() - 1 >= currentPos) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeights.get(currentPos), MeasureSpec.EXACTLY);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    private void obtainMinHeightAttribute(@NonNull Context context, @Nullable AttributeSet attrs) {
        int[] heightAttr = new int[]{android.R.attr.minHeight};
        TypedArray typedArray = context.obtainStyledAttributes(attrs, heightAttr);
        minHeight = typedArray.getDimensionPixelOffset(0, -666);
        typedArray.recycle();
    }

    private void setOnPageChangeListener() {
        this.addOnPageChangeListener(new SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                currentPos = position;

                ViewGroup.LayoutParams layoutParams = ChildWrappingAdjustableViewPager.this.getLayoutParams();
                layoutParams.height = childHeights.get(position);
                ChildWrappingAdjustableViewPager.this.setLayoutParams(layoutParams);
                ChildWrappingAdjustableViewPager.this.invalidate();
            }
        });
    }
}

সুতরাং এই অ্যাডাপ্টারের একটি বিশাল সমস্যা রয়েছে যখন অ্যাডাপ্টারের আইটেমগুলির
পরিমাণগুলি

আপনি কি আপনার বক্তব্য স্পষ্ট করতে পারেন?
Phatee পি

এই কোডটি নালপয়েন্টার তৈরি করতে পারে কারণ প্রতিটি শিশু শুরুতে গণনা করা হয় না। একটি ট্যাব বিন্যাস চেষ্টা করে 1 থেকে 5 বা কোড অনুসারে স্ক্রোল করুন এবং আপনি এটি দেখতে পাবেন।
জববার্ট

4

উন্নত ড্যানিয়েল ল্যাপেজ ল্যাকাল উত্তর, কোটলিনে আবার লিখেছেন :

class MyViewPager(context: Context, attrs: AttributeSet): ViewPager(context, attrs) {
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val zeroHeight = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)

        val maxHeight = children
            .map { it.measure(widthMeasureSpec, zeroHeight); it.measuredHeight }
            .max() ?: 0

        if (maxHeight > 0) {
            val maxHeightSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.EXACTLY)
            super.onMeasure(widthMeasureSpec, maxHeightSpec)
            return
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }
}

3

আমি একই ইস্যুতে ঝাঁপিয়ে পড়েছিলাম এবং যখন ব্যবহারকারী পৃষ্ঠাগুলির মধ্যে স্ক্রোল করেন তখন আমাকে ভিউপাগারটিকে তার সামগ্রীর চারপাশে মোড়ানোও করতে হয়েছিল। সাইবারজেনের উপরের উত্তরটি ব্যবহার করে, আমি onMeasure পদ্ধতিটি নিম্নলিখিত হিসাবে সংজ্ঞায়িত করেছি:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    if (getCurrentItem() < getChildCount()) {
        View child = getChildAt(getCurrentItem());
        if (child.getVisibility() != GONE) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
                    MeasureSpec.UNSPECIFIED);
            child.measure(widthMeasureSpec, heightMeasureSpec);
        }

        setMeasuredDimension(getMeasuredWidth(), measureHeight(heightMeasureSpec, getChildAt(getCurrentItem())));            
    }
}

এইভাবে, অনমিজার পদ্ধতিটি ভিউপ্যাজারের দ্বারা প্রদর্শিত বর্তমান পৃষ্ঠার উচ্চতা নির্ধারণ করে।


কেবলমাত্র আপনার উত্তরের সাথে সর্বাধিক উচ্চতার সামগ্রী প্রদর্শিত হবে, অন্য সামগ্রীটি অদৃশ্য হয়ে যাবে ...
ব্লেজ তামা

2

উপরে প্রস্তাবিত কিছুই আমার জন্য কাজ করে না। আমার ব্যবহারের ক্ষেত্রে 4 টি কাস্টম ভিউপ্যাজার রয়েছে ScrollView। এগুলির শীর্ষগুলি অনুপাতের অনুপাতের ভিত্তিতে পরিমাপ করা হয় এবং বাকিগুলি কেবলমাত্র layout_height=wrap_content। আমি সাইবারজেন চেষ্টা করেছি , ড্যানিয়েল ল্যাপেজ ল্যাকাল সলিউশন। তাদের কেউই আমার পক্ষে পুরোপুরি কাজ করে না।

আমার অনুমান সাইবারজেন পৃষ্ঠা 1 এ কেন কাজ করে না কারণ এটি পৃষ্ঠা 1 এর উপর ভিত্তি করে পেজারের উচ্চতা গণনা করে, আপনি আরও স্ক্রোল করলে এটি লুকিয়ে থাকে।

সাইবারজেন এবং ড্যানিয়েল ল্যাপেজ লাকাল পরামর্শ উভয়েরই আমার ক্ষেত্রে এক অদ্ভুত আচরণ রয়েছে: 3 টির মধ্যে 2 টি লোড করা ঠিক আছে এবং 1 টি এলোমেলো উচ্চতা 0। এটি onMeasureশিশুদের বসার আগে ডাকা হয়েছিল বলে মনে হয়। সুতরাং আমি এই 2 টি উত্তর + আমার নিজের ফিক্সগুলির মিশ্রণ নিয়ে এসেছি:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    if (getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT) {
        // find the first child view
        View view = getChildAt(0);
        if (view != null) {
            // measure the first child view with the specified measure spec
            view.measure(widthMeasureSpec, heightMeasureSpec);
            int h = view.getMeasuredHeight();
            setMeasuredDimension(getMeasuredWidth(), h);
            //do not recalculate height anymore
            getLayoutParams().height = h;
        }
    }
}

আইডিয়াটি হ'ল ViewPagerবাচ্চাদের মাত্রাগুলি গণনা করা এবং এর লেআউট প্যারামে প্রথম পৃষ্ঠার গণনা করা উচ্চতা সংরক্ষণ করা ViewPager। খণ্ডের বিন্যাসের উচ্চতা সেট করতে ভুলবেন না wrap_contentঅন্যথায় আপনি উচ্চতা = 0 পেতে পারেন। আমি এটি ব্যবহার করেছি:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="wrap_content">
        <!-- Childs are populated in fragment -->
</LinearLayout>

দয়া করে মনে রাখবেন যে আপনার সমস্ত পৃষ্ঠাগুলির উচ্চতা একই থাকলে এই সমাধানটি দুর্দান্ত কাজ করে । অন্যথায় আপনার ViewPagerবর্তমান শিশু সক্রিয় উপর ভিত্তি করে উচ্চতা গণনা করা প্রয়োজন । আমার এটির দরকার নেই, তবে আপনি যদি সমাধানটি প্রস্তাব করেন তবে আমি উত্তরটি আপডেট করে খুশি হব।


এত বছর পরেও আপনি কি নিজের উত্তর আপডেট করতে পারবেন? আমাকে এক টন সহায়তা করবে
ডেনি

2

এই সমস্যাযুক্ত লোকদের জন্য এবং সি # তে জামারিন অ্যান্ড্রয়েডের কোডিং, এটিও দ্রুত সমাধান হতে পারে:

pager.ChildViewAdded += (sender, e) => {
    e.Child.Measure ((int)MeasureSpecMode.Unspecified, (int)MeasureSpecMode.Unspecified);
    e.Parent.LayoutParameters.Height = e.Child.MeasuredHeight;
};

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

যদিও সমাধানটি নিজেই আমার পক্ষে যথেষ্ট নয় তবে এটি হ'ল আমার বাচ্চাদের আইটেমগুলি তালিকাভুক্ত এবং তাদের পরিমাপযোগ্য উচ্চতা সঠিকভাবে গণনা করা হয় না বলে মনে হয়।


এটি আমার পক্ষে কাজ করেছে। ভিউপ্যাজারে আমার সমস্ত শিশু দর্শন একই উচ্চতার।
দিমিত্রি

2

আমার কাছে র্যাপকন্টেন্টহাইটভিউপেজারের একটি সংস্করণ রয়েছে যা এপিআই 23 এর পূর্বে সঠিকভাবে কাজ করছিল যা নির্বাচিত বর্তমান সন্তানের দৃশ্যে পিতামাতার দৃশ্যের উচ্চতার ভিত্তিকে পুনরায় আকার দেবে।

23 এপিআইতে আপগ্রেড করার পরে, এটি কাজ করা বন্ধ করে দিয়েছে। দেখা যাচ্ছে যে পুরানো সমাধানটি getChildAt(getCurrentItem())বর্তমান সন্তানের দৃষ্টিভঙ্গিটি পরিমাপ করার জন্য ব্যবহার করছে যা কোন কাজ করছে না। এখানে সমাধান দেখুন: https://stackoverflow.com/a/16512217/1265583

নীচে API 23 এর সাথে কাজ করে:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int height = 0;
    ViewPagerAdapter adapter = (ViewPagerAdapter)getAdapter();
    View child = adapter.getItem(getCurrentItem()).getView();
    if(child != null) {
        child.measure(widthMeasureSpec,  MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        height = child.getMeasuredHeight();
    }
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

ধন্যবাদ!! ঘন্টাখানেক ধরে উত্তর চেষ্টা করে আসছি এবং এটি কেবলমাত্র আমার জন্য সম্পূর্ণরূপে কাজ করে। এটি একটি কাস্টম অ্যাডাপ্টারের সাথে একত্রীকরণ করা দরকার যেখানে 'সেটপ্রাইমারি আইটেম () the পেজারে এমন একটি ফাংশন কল করে যা কল করে requestLayout()যাতে আমরা এক ট্যাব থেকে পরের ট্যাবটিতে যেতে পারি তাই উচ্চতা সামঞ্জস্য করা হয়। মনে আছে superদু'বার ডাকার দরকার কেন ? আমি লক্ষ্য করেছি যে এটি অন্যথায় কাজ করবে না।
M3RS

এপিআই 28 এর সাথে কাজ করে
খালিদ লখানী

2

নীচের কোডটি আমার পক্ষে কাজ করেছে

1. এই ক্লাসটি হাইট র‍্যাপিংভিউপেজার ঘোষণার জন্য ব্যবহার করুন:

 public class HeightWrappingViewPager extends ViewPager {

        public HeightWrappingViewPager(Context context) {
            super(context);
        }

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

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int mode = MeasureSpec.getMode(heightMeasureSpec);
            // Unspecified means that the ViewPager is in a ScrollView WRAP_CONTENT.
            // At Most means that the ViewPager is not in a ScrollView WRAP_CONTENT.
            if (mode == MeasureSpec.UNSPECIFIED || mode == MeasureSpec.AT_MOST) {
                // super has to be called in the beginning so the child views can be initialized.
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
                int height = 0;
                for (int i = 0; i < getChildCount(); i++) {
                    View child = getChildAt(i);
                    child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
                    int h = child.getMeasuredHeight();
                    if (h > height) height = h;
                }
                heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
            }
            // super has to be called again so the new specs are treated as exact measurements
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

২. আপনার এক্সএমএল ফাইলে উচ্চতা মোড়ানো ভিউ পেজারটি প্রবেশ করান:

<com.project.test.HeightWrappingViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</com.project.test.HeightWrappingViewPager>

৩. আপনার দর্শন পেজার ঘোষণা করুন:

HeightWrappingViewPager mViewPager;
mViewPager = (HeightWrappingViewPager) itemView.findViewById(R.id.pager);
CustomAdapter adapter = new CustomAdapter(context);
mViewPager.setAdapter(adapter);
mViewPager.measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);

ধন্যবাদ। এটি কাজ করে। তবে অ্যান্ড্রয়েড দল কেন তাদের কোড বেসে থাকতে পারে না?
মোহনকৃষ্ণ

এটি আপনাকে নিজেরাই কাস্টমাইজ করতে হবে এমন একটি বিষয় যা আপনার প্রয়োজনের উপর নির্ভর করে, এছাড়াও গুগল এই বছরের 2019 সালে ভিউপ্যাজার 2 চালু করেছে গুগল আই / ও এবং পুরানো ভিউপ্যাজারের একটি প্রতিস্থাপন, যা ২০১১ সালে তৈরি হয়েছিল, androidx.viewpager2: ভিউপেজার 2 : 1.0.0-alpha04 '
হোসাম হাসান

2

নির্বাচিত আইটেমের উপর নির্ভর করে ভিউপ্যাজারকে উচ্চতা পরিবর্তন করার জন্য আমি সাইবারজেনের উত্তরটি সম্পাদনা করি ক্লাসটি সাইবারজেনের সমান, তবে আমি সংখ্যার একটি ভেক্টর যুক্ত করেছি যা সমস্ত দর্শকের সন্তানের দেখায় উচ্চতা এবং আমরা যখন পৃষ্ঠা পরিবর্তন করে উচ্চতা আপডেট করতে পারি তখন আমরা এটি অ্যাক্সেস করতে পারি

এই শ্রেণি:

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.ViewPager;

import java.util.Vector;

public class WrapContentHeightViewPager extends ViewPager {
    private Vector<Integer> heights = new Vector<>();

    public WrapContentHeightViewPager(@NonNull Context context) {
        super(context);
    }

    public WrapContentHeightViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        for(int i=0;i<getChildCount();i++) {
            View view = getChildAt(i);
            if (view != null) {
                view.measure(widthMeasureSpec, heightMeasureSpec);
                heights.add(measureHeight(heightMeasureSpec, view));
            }
        }
        setMeasuredDimension(getMeasuredWidth(), measureHeight(heightMeasureSpec, getChildAt(0)));
    }

    public int getHeightAt(int position){
        return heights.get(position);
    }

    private int measureHeight(int measureSpec, View view) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            if (view != null) {
                result = view.getMeasuredHeight();
            }
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }
}

তারপরে আপনার ক্রিয়াকলাপে একটি অনপেজ চেঞ্জলিস্টনার যুক্ত করুন

WrapContentHeightViewPager viewPager = findViewById(R.id.my_viewpager);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
     @Override
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
     @Override
     public void onPageSelected(int position) {
         LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) viewPager.getLayoutParams();
         params.height = viewPager.getHeightAt(position);
         viewPager.setLayoutParams(params);
     }
     @Override
     public void onPageScrollStateChanged(int state) {}
});

এবং এখানে এক্সএমএল:

<com.example.example.WrapContentHeightViewPager
    android:id="@+id/my_viewpager"
    android:fillViewport="true"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

প্রয়োজনে দয়া করে আমার ইংরেজি সংশোধন করুন


এটিতে কিছু সমস্যা রয়েছে। heightsতালিকা অনন্ত বৃদ্ধি হতে পারে।
rosuh

@rosuh আপনি কখন এই সমস্যার মুখোমুখি হয়েছেন? আমি এটি কেবলমাত্র ভিউপ্যাজারের সাথে ট্যাবলআউটটিতে ব্যবহার করেছি, সুতরাং আমি নিশ্চিত নই যে এটি সর্বত্র ভালভাবে কাজ করে কিনা
geggiamarti

@geggiamarti সমস্যাটি হ'ল কিছু পৃষ্ঠাগুলি পুনর্ব্যবহার করা হবে। এবং পুনরায় তৈরি যখন ব্যবহারকারী তাদের কাছে সোয়াইপ করে তাই measureবহু বার কল হবে call এটি উচ্চতার তালিকাকে বাড়িয়ে তুলতে পারে। আরেকটি পরিস্থিতি হ'ল এই ভিউপ্যাজারের জন্য ব্যবহারকারী নিজে নিজে কল করতে পারেন requestLayout(বা setLayoutParamsপদ্ধতি, যেমন আপনি করেছিলেন) একই সাথে বহু বার পরিমাপ করবে।
রসুহ

1

ViewPagerআপনি যদি ব্যবহার করছেন যদি এটি একটি শিশু ScrollView এবং এর একটি PagerTitleStripশিশু থাকে তবে আপনাকে ইতিমধ্যে সরবরাহ করা দুর্দান্ত উত্তরের কিছুটা পরিবর্তন করতে হবে। রেফারেন্সের জন্য আমার এক্সএমএল দেখতে এই রকম:

<ScrollView
    android:id="@+id/match_scroll_view"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/white">

    <LinearLayout
        android:id="@+id/match_and_graphs_wrapper"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <view
            android:id="@+id/pager"
            class="com.printandpixel.lolhistory.util.WrapContentHeightViewPager"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.v4.view.PagerTitleStrip
                android:id="@+id/pager_title_strip"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="top"
                android:background="#33b5e5"
                android:paddingBottom="4dp"
                android:paddingTop="4dp"
                android:textColor="#fff" />
        </view>
    </LinearLayout>
</ScrollView>

আপনার onMeasureআপনি করতে হবে ADD এর measuredHeight PagerTitleStripযদি এক পাওয়া যায়। অন্যথায় এটির উচ্চতা সমস্ত শিশুদের বৃহত্তম উচ্চতায় বিবেচিত হবে না যদিও এটি অতিরিক্ত জায়গা নেয়।

আশাকরি এটি কাউকে সাহায্য করবে। দুঃখিত যে এটি কিছুটা হ্যাক ...

public class WrapContentHeightViewPager extends ViewPager {

    public WrapContentHeightViewPager(Context context) {
        super(context);
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int pagerTitleStripHeight = 0;
        int height = 0;
        for(int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if (h > height) {
                // get the measuredHeight of the tallest fragment
                height = h;
            }
            if (child.getClass() == PagerTitleStrip.class) {
                // store the measured height of the pagerTitleStrip if one is found. This will only
                // happen if you have a android.support.v4.view.PagerTitleStrip as a direct child
                // of this class in your XML.
                pagerTitleStripHeight = h;
            }
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height+pagerTitleStripHeight, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

1

আমি এখানে দেখি বেশিরভাগ সমাধানগুলি দ্বৈত পরিমাপ করছে বলে মনে হচ্ছে: প্রথমে সন্তানের দৃষ্টিভঙ্গিগুলি পরিমাপ করুন এবং তারপরে ফোন করুন super.onMeasure()

আমি একটি কাস্টম নিয়ে এসেছি WrapContentViewPagerযা আরও দক্ষ, পুনর্ব্যবহারযোগ্য এবং খণ্ডের সাথে ভাল কাজ করে

আপনি এখানে ডেমো পরীক্ষা করতে পারেন:

GitHub / ssynhtn / WrapContentViewPager

এবং এখানে শ্রেণীর কোড: WrapContentViewPager.java


0

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

বিদ্যমান উত্তরগুলির মধ্যে কোনওটিই এই নির্দিষ্ট দৃশ্যের জন্য পুরোপুরি কাজ করেনি। ধরুন - এটি একটি দুরন্ত যাত্রী।

void setupView() {
    final ViewPager.SimpleOnPageChangeListener pageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            currentPagePosition = position;

            // Update the viewPager height for the current view

            /*
            Borrowed from https://github.com/rnevet/WCViewPager/blob/master/wcviewpager/src/main/java/nevet/me/wcviewpager/WrapContentViewPager.java
            Gather the height of the "decor" views, since this height isn't included
            when measuring each page's view height.
             */
            int decorHeight = 0;
            for (int i = 0; i < viewPager.getChildCount(); i++) {
                View child = viewPager.getChildAt(i);
                ViewPager.LayoutParams lp = (ViewPager.LayoutParams) child.getLayoutParams();
                if (lp != null && lp.isDecor) {
                    int vgrav = lp.gravity & Gravity.VERTICAL_GRAVITY_MASK;
                    boolean consumeVertical = vgrav == Gravity.TOP || vgrav == Gravity.BOTTOM;
                    if (consumeVertical) {
                        decorHeight += child.getMeasuredHeight();
                    }
                }
            }

            int newHeight = decorHeight;

            switch (position) {
                case PAGE_WITH_SHORT_AND_STATIC_CONTENT:
                    newHeight += measureViewHeight(thePageView1);
                    break;
                case PAGE_TO_FILL_PARENT:
                    newHeight = ViewGroup.LayoutParams.MATCH_PARENT;
                    break;
                case PAGE_TO_WRAP_CONTENT:
//                  newHeight = ViewGroup.LayoutParams.WRAP_CONTENT; // Works same as MATCH_PARENT because...reasons...
//                  newHeight += measureViewHeight(thePageView2); // Doesn't allow scrolling when sideways and height is clipped

                    /*
                    Only option that allows the ScrollView content to scroll fully.
                    Just doing this might be way too tall, especially on tablets.
                    (Will shrink it down below)
                     */
                    newHeight = ViewGroup.LayoutParams.MATCH_PARENT;
                    break;
            }

            // Update the height
            ViewGroup.LayoutParams layoutParams = viewPager.getLayoutParams();
            layoutParams.height = newHeight;
            viewPager.setLayoutParams(layoutParams);

            if (position == PAGE_TO_WRAP_CONTENT) {
                // This page should wrap content

                // Measure height of the scrollview child
                View scrollViewChild = ...; // (generally this is a LinearLayout)
                int scrollViewChildHeight = scrollViewChild.getHeight(); // full height (even portion which can't be shown)
                // ^ doesn't need measureViewHeight() because... reasons...

                if (viewPager.getHeight() > scrollViewChildHeight) { // View pager too tall?
                    // Wrap view pager height down to child height
                    newHeight = scrollViewChildHeight + decorHeight;

                    ViewGroup.LayoutParams layoutParams2 = viewPager.getLayoutParams();
                    layoutParams2.height = newHeight;
                    viewPager.setLayoutParams(layoutParams2);
                }
            }

            // Bonus goodies :)
            // Show or hide the keyboard as appropriate. (Some pages have EditTexts, some don't)
            switch (position) {
                // This case takes a little bit more aggressive code than usual

                if (position needs keyboard shown){
                    showKeyboardForEditText();
                } else if {
                    hideKeyboard();
                }
            }
        }
    };

    viewPager.addOnPageChangeListener(pageChangeListener);

    viewPager.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    // http://stackoverflow.com/a/4406090/4176104
                    // Do things which require the views to have their height populated here
                    pageChangeListener.onPageSelected(currentPagePosition); // fix the height of the first page

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                        viewPager.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    } else {
                        viewPager.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    }

                }
            }
    );
}


...

private void showKeyboardForEditText() {
    // Make the keyboard appear.
    getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

    inputViewToFocus.requestFocus();

    // http://stackoverflow.com/a/5617130/4176104
    InputMethodManager inputMethodManager =
            (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    inputMethodManager.toggleSoftInputFromWindow(
            inputViewToFocus.getApplicationWindowToken(),
            InputMethodManager.SHOW_IMPLICIT, 0);
}

...

/**
 * Hide the keyboard - http://stackoverflow.com/a/8785471
 */
private void hideKeyboard() {
    InputMethodManager inputManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);

    inputManager.hideSoftInputFromWindow(inputBibleBookStart.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}

...

//https://github.com/rnevet/WCViewPager/blob/master/wcviewpager/src/main/java/nevet/me/wcviewpager/WrapContentViewPager.java
private int measureViewHeight(View view) {
    view.measure(ViewGroup.getChildMeasureSpec(-1, -1, view.getLayoutParams().width), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    return view.getMeasuredHeight();
}

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


0

আমার ক্ষেত্রে clipToPaddingসমস্যা সমাধান করা।

<android.support.v4.view.ViewPager
    ...
    android:clipToPadding="false"
    ...
    />

চিয়ার্স!


0

আমি আমার কেসটি অ্যান্ড্রয়েড যুক্ত করছি: ফিলভিউপোর্ট = "সত্য" সমস্যাটি সমাধান করেছে


0

আমার ক্ষেত্রে, বর্তমানে সাইজটি প্রয়োগ করার সময় আমার নির্বাচিত উপাদান এবং অ্যানিমেশনের জন্য র্যাপ_ কনটেন্ট সহ একটি ভিউপেজার প্রয়োজন। নীচে আপনি আমার বাস্তবায়ন দেখতে পাবেন। কেউ কি কাজে আসতে পারে?

package one.xcorp.widget

import android.animation.ValueAnimator
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import one.xcorp.widget.R
import kotlin.properties.Delegates.observable

class ViewPager : android.support.v4.view.ViewPager {

    var enableAnimation by observable(false) { _, _, enable ->
        if (enable) {
            addOnPageChangeListener(onPageChangeListener)
        } else {
            removeOnPageChangeListener(onPageChangeListener)
        }
    }

    private var animationDuration = 0L
    private var animator: ValueAnimator? = null

    constructor (context: Context) : super(context) {
        init(context, null)
    }

    constructor (context: Context, attrs: AttributeSet?) : super(context, attrs) {
        init(context, attrs)
    }

    private fun init(context: Context, attrs: AttributeSet?) {
        context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.ViewPager,
            0,
            0
        ).apply {
            try {
                enableAnimation = getBoolean(
                    R.styleable.ViewPager_enableAnimation,
                    enableAnimation
                )
                animationDuration = getInteger(
                    R.styleable.ViewPager_animationDuration,
                    resources.getInteger(android.R.integer.config_shortAnimTime)
                ).toLong()
            } finally {
                recycle()
            }
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)

        val measuredHeight = if (heightMode == MeasureSpec.EXACTLY) {
            MeasureSpec.getSize(heightMeasureSpec)
        } else {
            val currentViewHeight = findViewByPosition(currentItem)?.also {
                measureView(it)
            }?.measuredHeight ?: 0

            if (heightMode != MeasureSpec.AT_MOST) {
                currentViewHeight
            } else {
                Math.min(
                    currentViewHeight,
                    MeasureSpec.getSize(heightMeasureSpec)
                )
            }
        }

        super.onMeasure(
            widthMeasureSpec,
            MeasureSpec.makeMeasureSpec(measuredHeight, MeasureSpec.EXACTLY)
        )
    }

    private fun measureView(view: View) = with(view) {
        val horizontalMode: Int
        val horizontalSize: Int
        when (layoutParams.width) {
            MATCH_PARENT -> {
                horizontalMode = MeasureSpec.EXACTLY
                horizontalSize = this@ViewPager.measuredWidth
            }
            WRAP_CONTENT -> {
                horizontalMode = MeasureSpec.UNSPECIFIED
                horizontalSize = 0
            }
            else -> {
                horizontalMode = MeasureSpec.EXACTLY
                horizontalSize = layoutParams.width
            }
        }

        val verticalMode: Int
        val verticalSize: Int
        when (layoutParams.height) {
            MATCH_PARENT -> {
                verticalMode = MeasureSpec.EXACTLY
                verticalSize = this@ViewPager.measuredHeight
            }
            WRAP_CONTENT -> {
                verticalMode = MeasureSpec.UNSPECIFIED
                verticalSize = 0
            }
            else -> {
                verticalMode = MeasureSpec.EXACTLY
                verticalSize = layoutParams.height
            }
        }

        val horizontalMeasureSpec = MeasureSpec.makeMeasureSpec(horizontalSize, horizontalMode)
        val verticalMeasureSpec = MeasureSpec.makeMeasureSpec(verticalSize, verticalMode)

        measure(horizontalMeasureSpec, verticalMeasureSpec)
    }

    private fun findViewByPosition(position: Int): View? {
        for (i in 0 until childCount) {
            val childView = getChildAt(i)
            val childLayoutParams = childView.layoutParams as LayoutParams

            val childPosition by lazy {
                val field = childLayoutParams.javaClass.getDeclaredField("position")
                field.isAccessible = true
                field.get(childLayoutParams) as Int
            }

            if (!childLayoutParams.isDecor && position == childPosition) {
                return childView
            }
        }

        return null
    }

    private fun animateContentHeight(childView: View, fromHeight: Int, toHeight: Int) {
        animator?.cancel()

        if (fromHeight == toHeight) {
            return
        }

        animator = ValueAnimator.ofInt(fromHeight, toHeight).apply {
            addUpdateListener {
                measureView(childView)
                if (childView.measuredHeight != toHeight) {
                    animateContentHeight(childView, height, childView.measuredHeight)
                } else {
                    layoutParams.height = animatedValue as Int
                    requestLayout()
                }
            }
            duration = animationDuration
            start()
        }
    }

    private val onPageChangeListener = object : OnPageChangeListener {

        override fun onPageScrollStateChanged(state: Int) {
            /* do nothing */
        }

        override fun onPageScrolled(
            position: Int,
            positionOffset: Float,
            positionOffsetPixels: Int
        ) {
            /* do nothing */
        }

        override fun onPageSelected(position: Int) {
            if (!isAttachedToWindow) {
                return
            }

            findViewByPosition(position)?.let { childView ->
                measureView(childView)
                animateContentHeight(childView, height, childView.measuredHeight)
            }
        }
    }
}

প্রকল্পে attrs.xML যুক্ত করুন:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ViewPager">
        <attr name="enableAnimation" format="boolean" />
        <attr name="animationDuration" format="integer" />
    </declare-styleable>
</resources>

আর ব্যবহার করুন:

<one.xcorp.widget.ViewPager
    android:id="@+id/wt_content"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:enableAnimation="true" />

0

এই ভিউপ্যাজারটি কেবলমাত্র বর্তমান দৃশ্যমান শিশুদেরই আকার দেয় (এটি প্রকৃত শিশুদের মধ্যে সবচেয়ে বড় নয়)

Https://stackoverflow.com/a/56325869/4718406 থেকে ধারণা

public class DynamicHeightViewPager extends ViewPager {

public DynamicHeightViewPager (Context context) {
    super(context);
    initPageChangeListener();
}

public DynamicHeightViewPager (Context context, AttributeSet attrs) {
    super(context, attrs);
    initPageChangeListener();
}



private void initPageChangeListener() {
    addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            requestLayout();
        }
    });
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    //View child = getChildAt(getCurrentItem());
    View child = getCurrentView(this);
    if (child != null) {
        child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, 
         MeasureSpec.UNSPECIFIED));
        int h = child.getMeasuredHeight();

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}


View getCurrentView(ViewPager viewPager) {
    try {
        final int currentItem = viewPager.getCurrentItem();
        for (int i = 0; i < viewPager.getChildCount(); i++) {
            final View child = viewPager.getChildAt(i);
            final ViewPager.LayoutParams layoutParams = (ViewPager.LayoutParams) 
             child.getLayoutParams();

            Field f = layoutParams.getClass().getDeclaredField("position"); 
            //NoSuchFieldException
            f.setAccessible(true);
            int position = (Integer) f.get(layoutParams); //IllegalAccessException

            if (!layoutParams.isDecor && currentItem == position) {
                return child;
            }
        }
    } catch (NoSuchFieldException e) {
        e.fillInStackTrace();
    } catch (IllegalArgumentException e) {
        e.fillInStackTrace();
    } catch (IllegalAccessException e) {
        e.fillInStackTrace();
    }
    return null;
}

}


0

ভিউপ্যাজারের উচ্চতা পরিমাপ করুন:

public class WrapViewPager extends ViewPager {
    View primaryView;

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (primaryView != null) {
            int height = 0;
            for (int i = 0; i < getChildCount(); i++) {
                if (primaryView == getChildAt(i)) {
                    int childHeightSpec = MeasureSpec.makeMeasureSpec(0x1 << 30 - 1, MeasureSpec.AT_MOST);
                    getChildAt(i).measure(widthMeasureSpec, childHeightSpec);
                    height = getChildAt(i).getMeasuredHeight();
                }

            }

            setMeasuredDimension(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
        }
    }

    public void setPrimaryView(View view) {
        primaryView = view;
    }

}

কল সেটপ্রাইমারিভিউ (দেখুন) :

public class ZGAdapter extends PagerAdapter {

    @Override
    public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        super.setPrimaryItem(container, position, object);
        ((WrapViewPager)container).setPrimaryView((View)object);
    }

}

0

এর মতো ভিউপ্যাজারের পিতামাতার বিন্যাসটি দিন NestedScrollView

   <androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="5dp"
    android:paddingRight="5dp"
    android:fillViewport="true">
        <androidx.viewpager.widget.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </androidx.viewpager.widget.ViewPager>
    </androidx.core.widget.NestedScrollView>

সেট করতে ভুলবেন না android:fillViewport="true"

এটি ভিউপোর্টটি পূরণের জন্য স্ক্রোলভিউ এবং তার সন্তানের সামগ্রী প্রসারিত করবে।

https://developer.android.com/reference/android/widget/ScrollView.html#attr_android:fillViewport


0

আপনি ভিউপ্যাজার 2 এ স্যুইচ করতে পারেন। এটি ভিউপ্যাজারের একটি আপডেট সংস্করণ। এটি ভিউপ্যাজারের মতো একই কাজ করে তবে একটি স্মার্ট এবং দক্ষ উপায়ে। ভিউপেজার 2 বিভিন্ন ধরণের নতুন বৈশিষ্ট্য নিয়ে আসে। অবশ্যই মোড়ানো সামগ্রীর সমস্যাটি ভিউপ্যাজার 2 দ্বারা সমাধান করা হয়েছে।

অ্যান্ড্রয়েড ডক্স থেকে: "ভিউপাগার 2 ডান থেকে বাম লেআউট সমর্থন, উল্লম্ব অভিযোজন, সংশোধনযোগ্য ফ্রেগমেন্ট সংগ্রহ ইত্যাদিসহ তার পূর্বসূরীর বেশিরভাগ ব্যথা-পয়েন্টকে সম্বোধন করে ভিউপাগারকে প্রতিস্থাপন করে।"

আমি এই নিবন্ধটি নতুনদের জন্য সুপারিশ করছি:

https://medium.com/google-developer-experts/exploring-the-view-pager-2-86dbce06ff71


এই ইস্যুটি এখনও জারি করা আছে ইস্যুতেআরেকার জিইএলইউ
কুমার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.