তালিকাভিউয়ের পুনর্ব্যবহারযোগ্য প্রক্রিয়া কীভাবে কাজ করে


146

আমার আগে এই সমস্যাটি ছিল এবং স্বাভাবিকভাবেই আমি এখানে সহায়তা চেয়েছিলাম । লুকসপ্রোগের উত্তর দুর্দান্ত ছিল কারণ তালিকাভিউ এবং গ্রিডভিউ কীভাবে পুনর্ব্যবহারযোগ্য দৃশ্যের সাথে নিজেকে অনুকূল করে তুলেছিল সে সম্পর্কে আমার কোনও ধারণা ছিল না। তাই তাঁর পরামর্শ নিয়ে আমি কীভাবে আমার গ্রিডভিউতে ভিউ যুক্ত করেছি তা পরিবর্তন করতে সক্ষম হয়েছি। সমস্যা হ'ল আমার কাছে এমন কিছু আছে যা বোঝায় না। এটি আমার getViewকাছ থেকে BaseAdapter:


public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            convertView = inflater.inflate(R.layout.day_view_item, parent, false);
        }
        Log.d("DayViewActivity", "Position is: "+position);
        ((TextView)convertView.findViewById(R.id.day_hour_side)).setText(array[position]);
        LinearLayout layout = (LinearLayout)convertView.findViewById(R.id.day_event_layout);

        //layout.addView(new EventFrame(parent.getContext()));

        TextView create = new TextView(DayViewActivity.this);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 62, getResources().getDisplayMetrics()), 1.0f);
        params.topMargin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
        params.bottomMargin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
        create.setLayoutParams(params);
        create.setBackgroundColor(Color.BLUE);
        create.setText("Test"); 
        //the following is my original LinearLayout.LayoutParams for correctly setting the TextView Height
        //new LinearLayout.LayoutParams(0, (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, getResources().getDisplayMetrics()), 1.0f)   
        if(position == 0) {
            Log.d("DayViewActivity", "This should only be running when position is 0. The position is: "+position);
            layout.addView(create);
        }

        return convertView;
    }

}

সমস্যাটি যখন আমি স্ক্রোল করি, তখন এটি ঘটে এবং 0 পজিশনে নয় ... অবস্থান 6 এবং অবস্থান 8 এর মতো মনে হচ্ছে প্লাস এটি দুটি স্থানে 8 রাখে Now এখন আমি এখনও তালিকাভিউ এবং গ্রিডভিউ ব্যবহারের হ্যাং পেতে চেষ্টা করছি তাই আমি করি বুঝতে পারছিনা কেন এমন হচ্ছে। আমি এই প্রশ্নটি করার মূল কারণগুলির মধ্যে একটি হ'ল অন্যদের সহায়তা করা যা সম্ভবত তালিকাভিউ এবং গ্রিডভিউয়ের পুনর্ব্যবহারযোগ্য ভিউ সম্পর্কে জানেন না বা এই নিবন্ধটি যেভাবে রাখে, স্ক্র্যাপভিউ প্রক্রিয়া।

এখানে চিত্র বর্ণনা লিখুন

পরে সম্পাদনা করুন

গুগল আইও টকের সাথে লিঙ্ক যুক্ত করা যা মূলত তালিকাভিউ কীভাবে কাজ করে তা আপনার বুঝতে হবে। মন্তব্যে লিঙ্কটি মারা গিয়েছিল। সুতরাং ব্যবহারকারী 3427079 এই লিঙ্কটি আপডেট করার জন্য যথেষ্ট দুর্দান্ত ছিল। এখানে এটি সহজ অ্যাক্সেসের জন্য।


হাহাহা, এই লিঙ্কের জন্য ধন্যবাদ। এখনই এটি দেখা শুরু করেছেন :)
অ্যান্ডি

আপনি পূর্ববর্তী প্রশ্ন থেকে কোডের নমুনাকে পুরোপুরি প্রয়োগ করেননি। ধারণাটি হ'ল অন্যান্য সারিগুলির জন্য আপনার করা পরিবর্তনগুলি (আপনার ক্ষেত্রে অবস্থানে 0) আপনি ফিরে পেতে আপনার সর্বদা কোডের একটি অংশ থাকা দরকার ।
লুক্সপ্রোগ

আচ্ছা আমি বুঝতে পারি যে @ লুক্সপ্রোগ তবে এটি কী ব্যাখ্যা করে যে এটি অন্য অবস্থানগুলিতেও দৃষ্টিভঙ্গি রাখছে কেন? যদি কিছু হয় তবে আমি ডুপ্লিকেট ভিউগুলি কেবল 0 পজিশনে রেখেছি expected ইড্ক, কীভাবে তালিকাভিউ এই স্টাফটিকে বাঁধাই করছে তা বুঝতে এখনও সমস্যা হচ্ছে: /
অ্যান্ডি

1
পুনর্ব্যবহারের অর্থ হ'ল পর্দা থেকে সারি ভিউটি সবেমাত্র অদৃশ্য হয়ে গেছে (উদাহরণস্বরূপ অবস্থান 0, এক সারি নিচে স্ক্রোল করার পরে) পরে ব্যবহার করা যেতে পারে যখন ListViewদেখানোর জন্য কোনও নতুন সারি প্রয়োজন (যেমন ডাউন / উপরে স্ক্রোল চালিয়ে যাওয়া)। সমস্যাটি হ'ল যে দৃষ্টিভঙ্গিটি সবেমাত্র অদৃশ্য হয়ে গেছে এবং এটি ভবিষ্যতে প্রয়োজনীয় অবস্থানগুলিতে ব্যবহৃত হবে এটি TextViewইতিমধ্যে এতে যুক্ত হয়েছে, এটিই সমস্যা। এটির সমাধানের জন্য আপনাকে getViewপদ্ধতিতে এটি অপসারণ করতে হবে যদি getViewপদ্ধতিটি অন্য কোনও অবস্থানের জন্য কল করা হয় 0
লুক্সপ্রাগ

2
শীর্ষ পোস্টের লিঙ্কটি মারা গেছে, আমার মনে হয় এটি কি? youtube.com/watch?v=N6YdwzAvwOA
G_V

উত্তর:


330

প্রথমদিকে, আমি লিস্টভিউ পুনর্ব্যবহারযোগ্য এবং রূপান্তর ব্যবহারের পদ্ধতি সম্পর্কেও অবগত ছিলাম না, তবে পুরো এক দিন গবেষণা শেষে আমি android.amberfog এর কোনও চিত্র উল্লেখ করে তালিকার দৃশ্যের প্রক্রিয়াগুলি বেশ বুঝতে পারি এখানে চিত্র বর্ণনা লিখুন

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

System.out.println("getview:"+position+" "+convertView);

আপনার ভিতরে

public View getView(final int position, View convertView, ViewGroup parent)
{
    System.out.println("getview:"+position+" "+convertView);
    ViewHolder holder;
    View row=convertView;
    if(row==null)
    {
        LayoutInflater inflater=((Activity)context).getLayoutInflater();
        row=inflater.inflate(layoutResourceId, parent,false);
        
        holder=new PakistaniDrama();
        holder.tvDramaName=(TextView)row.findViewById(R.id.dramaName);
        holder.cbCheck=(CheckBox)row.findViewById(R.id.checkBox);
        
        row.setTag(holder);
        
    }
    else
    {
        holder=(PakistaniDrama)row.getTag();
    }
            holder.tvDramaName.setText(dramaList.get(position).getDramaName());
    holder.cbCheck.setChecked(checks.get(position));
            return row;
    }

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

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

গুরুত্বপূর্ণ বিষয়

। কখনো সেট layout_heightএবং layout_widthআপনার listview এর wrap_contentযেমন getView()মতামত উচ্চতা পরিমাপ তালিকা দৃশ্য টানা হতে কিছুটা শিশু পেতে আপনার অ্যাডাপ্টারের বাধ্য করা হবে এবং convertview এমনকি তালিকা ফেরার মত কিছু অপ্রত্যাশিত আচরণের সৃষ্টি করতে পারে না scrolled.always ব্যবহার match_parentবা নির্দিষ্ট প্রস্থ উচ্চতা.

। আপনি আপনার তালিকা দর্শন এবং জিজ্ঞাসাবাদ করে পরে কিছু লেআউট বা দৃশ্য ব্যবহার করতে চান তাহলে আপনার মনের মধ্যে এসে যদি আমি সেট layout_heightকরতে fill_parentতালিকা দর্শন পর দৃশ্য দেখানো হবে না যেমন, স্ক্রিন যায় নিচে, যাতে তার ভাল একটি ভিতরে আপনার listview করা লেআউট. উদাহরণস্বরূপ লিনিয়ার লেআউট এবং আপনার প্রয়োজনীয়তা অনুসারে সেই বিন্যাসটির উচ্চতা এবং প্রস্থ নির্ধারণ করুন এবং আপনার তালিকা বিন্যাসের উচ্চতা এবং প্রস্থের বৈশিষ্ট্যটিকে আপনার বিন্যাস হিসাবে তৈরি করুন (যেমন আপনার লেআউটের প্রস্থ 320 এবং উচ্চতা 280 হয়) তবে আপনার তালিকাভিউ একই উচ্চতা এবং প্রস্থ হওয়া উচিত। এটি রেন্ডার করার জন্য দৃশ্যের যথাযথ উচ্চতা এবং প্রস্থের getView () কে বলবে এবং getView () বার বার কিছু এলোমেলো সারি কল করবে না, এবং স্ক্রোলিংয়ের আগেই রূপান্তর ভিউ ফিরে আসার মতো অন্যান্য সমস্যা ঘটবে না, আমার পরীক্ষা আছে এটি নিজেই, যদি না আমার লিস্টভিউ লাইনের ভিতরে না থাকে তবে ভিউ কলটি পুনরাবৃত্তি করা এবং ভিউ রূপান্তর করা, লিনিয়ারলাইউটের ভিতরে লিস্টভিউ রাখার মতো সমস্যাও আমার মতো সমস্যা ছিল না (কেন জানি না)

01-01 14:49:36.606: I/System.out(13871): getview 0 null
01-01 14:49:36.636: I/System.out(13871): getview 0 android.widget.RelativeLayout@406082c0
01-01 14:49:36.636: I/System.out(13871): getview 1 android.widget.RelativeLayout@406082c0
01-01 14:49:36.646: I/System.out(13871): getview 2 android.widget.RelativeLayout@406082c0
01-01 14:49:36.646: I/System.out(13871): getview 3 android.widget.RelativeLayout@406082c0
01-01 14:49:36.656: I/System.out(13871): getview 4 android.widget.RelativeLayout@406082c0
01-01 14:49:36.666: I/System.out(13871): getview 5 android.widget.RelativeLayout@406082c0
01-01 14:49:36.666: I/System.out(13871): getview 0 android.widget.RelativeLayout@406082c0
01-01 14:49:36.696: I/System.out(13871): getview 0 android.widget.RelativeLayout@406082c0
01-01 14:49:36.706: I/System.out(13871): getview 1 null
01-01 14:49:36.736: I/System.out(13871): getview 2 null
01-01 14:49:36.756: I/System.out(13871): getview 3 null
01-01 14:49:36.776: I/System.out(13871): getview 4 null

তবে এখন এটি সমাধান হয়েছে, আমি জানি, আমি ব্যাখ্যা করার ক্ষেত্রে তেমন ভাল নই তবে আমি যেমন বুঝতে চেষ্টা করেছি আমার পুরো দিনটিকে তাই আমার মতো অন্যান্য নবজাতকরাও আমার অভিজ্ঞতার সাহায্য নিতে পারে এবং আমি আশা করি এখন আপনারা কিছুটা বুঝতে পারবেন এর ListView ফ্রেমওয়ার্ক কিভাবে এটি কাজ করে, যেমন এটি সত্যিই নোংরা এবং চতুর তাই নতুনদের এটা বুঝতে খুব বেশি সমস্যা পাওয়া যায়


36
"আমি বুঝতে পারছি না যে এটি ব্যাখ্যা করার ক্ষেত্রে আমি খুব ভাল" >>> এই উত্তরের +37৩ ভোট আমাকে বলে যে আপনি ব্যাখ্যা করার ক্ষেত্রে একটি দুর্দান্ত কাজ করেছেন। আপনার জ্ঞান ভাগ করে রাখুন দয়া করে! ;)
2

1
আমার কাছ থেকে দুর্দান্ত উত্তর রাজা জিৎ +1 .. :)
এহসান সাজ্জাদ

2
ছবিটির জন্য আপনাকে ধন্যবাদ। অ্যান্ড্রয়েডের সাথে শুরু করার সাথে তালিকার ভিউতে প্রচুর ঝামেলা করার পরে, আমি এত লড়াইয়ের পরে পুনর্ব্যবহারের নীতিটি ইতিমধ্যে জানতাম knew তবুও, এই ছবিটি এবং বাক্যটি নিয়েছিল: if you had a checkbox and if you check it at position 0(let say item1 has also a checkbox and you checked it) so when you scroll down you will see item 8 checkbox is already checked,this is why listview is re using the same view not creating a new for you due to performance optimization.আমার ভুলটি অনুধাবনের জন্য for অ্যান্ড্রয়েড লিস্টভিউ পুনর্ব্যবহার সম্পর্কে সেরা পোস্টটি আমি পেলাম!
কেভিন ক্রুইজসেন

1
: @MuhammadBabar হ্যাঁ, আমি প্রশ্ন পোস্ট করেছেন stackoverflow.com/q/30122027/1318946
প্রতীক Butani

1
@ মুহম্মদবাবারের দুর্দান্ত ব্যাখ্যা! এটি আমার সময় সাশ্রয় করে। শুধু জানতে চাই, RecyclerViewএকই পদ্ধতিতে কি কাজ করে? আমার প্রশ্নে স্ট্যাকওভারফ্লো.com / জিজ্ঞাসা / ৪৮৮৯777770০/২ , আমি জানি যে টাস্কটি নিখুঁতভাবে অসম্ভব listView। আমার সাথে চেষ্টা করা উচিত recyclerView?
শম্ভু

8

হোল্ডার প্যাটার্নে সাবধানতা অবলম্বন করুন, যদি আপনি নিজের ধারক বস্তুতে পোস্টটি সেট করেন তবে আপনার প্রতিবার এটি সেট করা উচিত, উদাহরণস্বরূপ:

@Override
public final View getView(int position, View view, ViewGroup parent) {
    Holder holder = null;
    if (view == null) {
        LayoutInflater inflater = (LayoutInflater) App.getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(getContainerView(), parent, false);
        holder = getHolder(position, view, parent);
        holder.setTag(tag);
        view.setTag(holder);
    } else {
        holder = (Holder) view.getTag();
    }
    holder.position = position;
    draw(holder);
    return holder.getView();
}

এটি একটি বিমূর্ত শ্রেণীর উদাহরণ, যেখানে

getHolder(position, view, parent);

এর জন্য সমস্ত সেটিং অপারেশন করে

ImageViews, TextViews, etc..

1
খেয়াল করিনি যে এই সময়টি আমি করছিলাম। parent.setTag(holder);সঠিক view.setTag(holder);
উপায়ের

2

ধারক নিদর্শন ব্যবহার করে আপনি যা চান তা অর্জন করতে পারেন:

আপনি এই প্যাটার্নটির বর্ণনা এখানে পাবেন:

তালিকার দৃশ্যের পুনর্ব্যবহার তখন ঘটে যখন আপনি স্ক্রিনটি নীচে স্ক্রোল করবেন এবং উপরে তালিকার ভিউ আইটেমগুলি লুকানো থাকবে। এগুলি নতুন তালিকা দেখার আইটেমগুলি দেখাতে পুনরায় ব্যবহার করা হয়েছে।

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