কীভাবে অ্যানড্রয়েড তালিকাগুলি সারিগুলি সংযোজন বা সরানো যায় তা কার্যকর করুন


212

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

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

আমি যখন পৃথক আইটেমটি সরিয়ে ফেলা হয় তখন প্রাণবন্ত করতে নীচের মতো জিনিসগুলি চেষ্টা করেছি:

@Override
protected void onListItemClick(ListView l, View v, final int position, long id) {
    Animation animation = new ScaleAnimation(1, 1, 1, 0);
    animation.setDuration(100);
    getListView().getChildAt(position).startAnimation(animation);
    l.postDelayed(new Runnable() {
        public void run() {
            mStringList.remove(position);
            mAdapter.notifyDataSetChanged();
        }
    }, 100);
}

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

আমার নিজের প্রয়োগ / লিস্টভিউয়ের কাঁটাচামচ লেখার সময় আমার মন কেটে গেছে, এটি এমন কিছু মনে হচ্ছে যা এতটা কঠিন নয়।

ধন্যবাদ!


কেউ কি এর উত্তর খুঁজে পেয়েছে? pls শাড়ি
অ্যান্ড্রয়েড গেকো

@ অ্যালেক্স: আপনি কি সেই অ্যানিমেশনটি ইউটিউব ভিডিওর মতো করেছেন (আইফোনের মতো), যদি আপনার অ্যান্ড্রয়েডের জন্য কোনও ডেমো বা লিঙ্ক থাকে তবে দয়া করে আমাকে দিন, আমি এক্সএমএল ফাইলে এনিমেট লেআউটচেন্জ ব্যবহার করার চেষ্টা করেছি, তবে এটি আইফোনের মতো নয়
জয়েশ

@ জয়েশ, দুর্ভাগ্যক্রমে আমি আর অ্যান্ড্রয়েড বিকাশে কাজ করি না। আমি এই প্রশ্নের উত্তর যে প্রায় 2012 এর পরে লেখা ছিল পরীক্ষা করিনি।
অ্যালেক্স Pretzlav

উত্তর:


124
Animation anim = AnimationUtils.loadAnimation(
                     GoTransitApp.this, android.R.anim.slide_out_right
                 );
anim.setDuration(500);
listView.getChildAt(index).startAnimation(anim );

new Handler().postDelayed(new Runnable() {

    public void run() {

        FavouritesManager.getInstance().remove(
            FavouritesManager.getInstance().getTripManagerAtIndex(index)
        );
        populateList();
        adapter.notifyDataSetChanged();

    }

}, anim.getDuration());

শীর্ষে থেকে ডাউন অ্যানিমেশন ব্যবহারের জন্য:

<set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate android:fromYDelta="20%p" android:toYDelta="-20"
            android:duration="@android:integer/config_mediumAnimTime"/>
        <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="@android:integer/config_mediumAnimTime" />
</set>

70
anim.setAnimationListener(new AnimationListener() { ... })হ্যান্ডলার ব্যবহার না করে ব্যবহার করা আরও ভাল
ওলেগ ভাস্কেভিচ

1
কি populateList()জন্য?
ভ্যাসিলি সোচিনস্কি

5
@ এমআরপ্লেলবিআর বিভিন্ন কারণে। প্রথমত, আপনি বিনা শর্তে তৈরি করছেন না Handler। দ্বিতীয়ত, অ্যানিমেশনটি শেষ হওয়ার জন্য এটি ইতিমধ্যে বিল্ট-ইন কলব্যাক ব্যবহার করে কোডটিকে কম জটিল করে তোলে। তৃতীয়, আপনি কীভাবে প্রতিটি প্ল্যাটফর্মের প্রয়োগ Handlerএবং Animationকাজ করবেন তা জানেন না ; অ্যানিমেশন শেষ হওয়ার আগেই আপনার বিলম্বিত চলমান ঘটনাটি ঘটতে পারে।
ওলেগ ভাস্কেভিচ

7
"তবে, অ্যানিমেটেড সারিটির চারপাশে থাকা সারিগুলি যখন notifyDataSetChanged () ডাকা হয় তখন তারা তাদের নতুন অবস্থানে না যায় ততক্ষণ পজিশনটি সরবে না।" এই সমস্যাটি এখনও আপনার সমাধানে টিকে আছে।
বরিস রুসেভ

5
ফেভারিটম্যানেজার ক্লাস এবং পপুলেটলিস্ট () পদ্ধতি কী ??
জয়েশ

14

1
আমি মনে করি আপনার যখন একটি সাধারণ অ্যানিমেশন প্রয়োজন তখন এটিই সহজ উপায় but
Qatz

2
চূড়ান্ত পদক্ষেপটি ছিল আমার অনুপস্থিত লিঙ্ক। স্থিতিশীল আইডি ধন্যবাদ!
আমির উওয়াল

এটি একটি দুর্দান্ত নমুনা প্রকল্প যা এপিআইকে ভালভাবে প্রদর্শন করে।
মিস্টার-আইডিই


2

যেহেতু ListViewsউচ্চতর অনুকূলিত হয়েছে আমি মনে করি এটি অর্জন সম্ভব নয়। আপনি কি কোড দ্বারা আপনার "লিস্টভিউ" তৈরি করার চেষ্টা করেছেন (যেমন এক্সএমএল থেকে আপনার সারিগুলি স্ফীত করে এবং এটিকে সংযোজন করে LinearLayout) এবং এনিমেট করে দিয়েছেন?


6
কেবলমাত্র অ্যানিমেশন যুক্ত করতে তালিকার পুনর্বিবেচনা করা কোনও অর্থবোধ করে না।
Macarse

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

আমি জানি এটি কোনও তাত্পর্যপূর্ণ নয় - তবে আপনি যদি কয়েকটি কয়েকটি সারি দিয়ে কাজ করেন তবে অ্যানিমেশনগুলি ভাল / আউট করার সুবিধাটি উপকারের হতে পারে।
WHLK

2

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


2

কল তালিকাভিউ.সচেডলআউটঅ্যানিমেশন (); তালিকা পরিবর্তন করার আগে


2

তালিকার ভিউটি হেরফের না করেই আমি এটি করার অন্য একসাথে হ্যাক করেছি। দুর্ভাগ্যক্রমে, নিয়মিত অ্যান্ড্রয়েড অ্যানিমেশনগুলি সারিটির বিষয়বস্তুগুলি হেরফের করছে বলে মনে হচ্ছে তবে দৃশ্যটি সঙ্কুচিত করার ক্ষেত্রে এটি অকার্যকর। সুতরাং, প্রথমে এই হ্যান্ডলারটি বিবেচনা করুন:

private Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
    Bundle bundle = message.getData();

    View view = listView.getChildAt(bundle.getInt("viewPosition") - 
        listView.getFirstVisiblePosition());

    int heightToSet;
    if(!bundle.containsKey("viewHeight")) {
        Rect rect = new Rect();
        view.getDrawingRect(rect);
        heightToSet = rect.height() - 1;
    } else {
        heightToSet = bundle.getInt("viewHeight");
    }

    setViewHeight(view, heightToSet);

    if(heightToSet == 1)
        return;

    Message nextMessage = obtainMessage();
    bundle.putInt("viewHeight", (heightToSet - 5 > 0) ? heightToSet - 5 : 1);
    nextMessage.setData(bundle);
    sendMessage(nextMessage);
}

আপনার তালিকা অ্যাডাপ্টারে এই সংগ্রহটি যুক্ত করুন:

private Collection<Integer> disabledViews = new ArrayList<Integer>();

এবং যোগ করুন

public boolean isEnabled(int position) {
   return !disabledViews.contains(position);
}

এরপরে, যেখানেই আপনি যে কোনও সারিটি গোপন করতে চান, এটি যুক্ত করুন:

Message message = handler.obtainMessage();
Bundle bundle = new Bundle();
bundle.putInt("viewPosition", listView.getPositionForView(view));
message.setData(bundle);
handler.sendMessage(message);    
disabledViews.add(listView.getPositionForView(view));

এটাই! আপনি একবারে উচ্চতা সঙ্কুচিত করে পিক্সেল সংখ্যা পরিবর্তন করে আপনি অ্যানিমেশনের গতি পরিবর্তন করতে পারেন। বাস্তব পরিশীলিত নয়, তবে এটি কার্যকর!


2

তালিকাভিউতে নতুন সারি সন্নিবেশ করার পরে, আমি কেবল তালিকাভিউকে নতুন অবস্থানে স্ক্রোল করব।

ListView.smoothScrollToPosition(position);

1

আমি এটি চেষ্টা করে দেখিনি তবে দেখে মনে হচ্ছে অ্যানিমেটলআউটচ্যাঞ্জসগুলি আপনি যা খুঁজছেন তা করা উচিত। আমি এটি ইমেজসুইচার ক্লাসে দেখছি, আমি ধরে নিয়েছি এটিও ভিউসুইচার ক্লাসে আছে?


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

1

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

এফওয়াইআই, তালিকা দেখার উত্স কোডটি এখানে


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

1

এখানে সোর্স কোডটিআপনাকে সারিগুলি মুছতে এবং সেগুলি পুনরায় সাজানোর জন্য ।

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


1

আমি আমার সাইটে আমার পদ্ধতির ব্যাখ্যা হিসাবে আমি লিঙ্কটি ভাগ করেছিলাম। যাইহোক ধারণাটি হ'ল বিটম্যাপগুলি গেটড্রাউচচে তৈরি করে create দুটি বিটম্যাপ করুন এবং চলমান প্রভাব তৈরি করতে নিম্ন বিটম্যাপটি সঞ্জীবিত করুন

দয়া করে নীচের কোডটি দেখুন:

listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
    {
        public void onItemClick(AdapterView<?> parent, View rowView, int positon, long id)
        {
            listView.setDrawingCacheEnabled(true);
            //listView.buildDrawingCache(true);
            bitmap = listView.getDrawingCache();
            myBitmap1 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), rowView.getBottom());
            myBitmap2 = Bitmap.createBitmap(bitmap, 0, rowView.getBottom(), bitmap.getWidth(), bitmap.getHeight() - myBitmap1.getHeight());
            listView.setDrawingCacheEnabled(false);
            imgView1.setBackgroundDrawable(new BitmapDrawable(getResources(), myBitmap1));
            imgView2.setBackgroundDrawable(new BitmapDrawable(getResources(), myBitmap2));
            imgView1.setVisibility(View.VISIBLE);
            imgView2.setVisibility(View.VISIBLE);
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            lp.setMargins(0, rowView.getBottom(), 0, 0);
            imgView2.setLayoutParams(lp);
            TranslateAnimation transanim = new TranslateAnimation(0, 0, 0, -rowView.getHeight());
            transanim.setDuration(400);
            transanim.setAnimationListener(new Animation.AnimationListener()
            {
                public void onAnimationStart(Animation animation)
                {
                }

                public void onAnimationRepeat(Animation animation)
                {
                }

                public void onAnimationEnd(Animation animation)
                {
                    imgView1.setVisibility(View.GONE);
                    imgView2.setVisibility(View.GONE);
                }
            });
            array.remove(positon);
            adapter.notifyDataSetChanged();
            imgView2.startAnimation(transanim);
        }
    });

চিত্রগুলির সাথে বোঝার জন্য এটি দেখুন

ধন্যবাদ।


0

আমি এরকম কিছু করেছি। একটি পদ্ধতির তালিকার ভিউয়ের জন্য onMeasureইস্যু requestLayout()করার সময় সারিগুলির মধ্যে সময়ের সাথে সাথে উচ্চতার অ্যানিমেশনের সময়কে ছড়িয়ে দেওয়া। হ্যাঁ সরাসরি ভিউ কোডের অভ্যন্তরে কাজ করা ভাল হতে পারে তবে এটি একটি দ্রুত সমাধান ছিল (এটি দেখতে ভাল লাগছিল!)


0

কেবল অন্য পদ্ধতির ভাগ করে নেওয়া:

প্রথম তালিকা দৃশ্যের সেট animateLayoutChanges: Android থেকে সত্য :

<ListView
        android:id="@+id/items_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true"/>

তারপরে আমি আইটেমগুলি যুক্ত করতে এবং দেরি সহ তালিকার ভিউ আপডেট করতে একটি হ্যান্ডলার ব্যবহার করি :

Handler mHandler = new Handler();
    //delay in milliseconds
    private int mInitialDelay = 1000;
    private final int DELAY_OFFSET = 1000;


public void addItem(final Integer item) {
    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    mDataSet.add(item);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            mAdapter.notifyDataSetChanged();
                        }
                    });
                }
            }).start();

        }
    }, mInitialDelay);
    mInitialDelay += DELAY_OFFSET;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.