তালিকার ভিউ অ্যাডহাইডারভিউ একের পর এক অবস্থান বাড়ায়?


97

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

সুতরাং শিরোনাম ছাড়াই প্রথম তালিকার উপাদানটির অবস্থান 0 হবে, শিরোনামের সাথে প্রথম তালিকার উপাদানটির অবস্থান হবে 1!

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

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ListView list = (ListView) viewSwitcher.findViewById(R.id.list);
    View emptyView = viewSwitcher.findViewById(R.id.empty);
    list.setEmptyView(emptyView);

    View sectionHeading = inflater.inflate(R.layout.heading, list, false);
    TextView sectionHeadingTextView = (TextView) sectionHeading.findViewById(R.id.headingText);
    sectionHeadingTextView.setText(headerText);
    list.addHeaderView(sectionHeading);

    list.setAdapter(listAdapter);

    list.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            listAdapter.getItem(position);
            //Do something with it
        }
    });
}

কিছু অ্যাডাপ্টার পদ্ধতি:

@Override
public int getViewTypeCount() {
    return TYPE_COUNT;
}

@Override
public int getItemViewType(int position) {
    return (position < items.size()) ? ITEM_NORMAL : ITEM_ADVANCED;
}

    @Override
public Product getItem(int position) {
    return items.get(position);
}
@Override
public boolean areAllItemsEnabled() {
    return false;
}

@Override
public boolean isEnabled(int position) {
    return (position < items.size());
}

হেডারভিউ যুক্ত করার সময় এটাই কি স্বাভাবিক আচরণ ?? এবং কিভাবে আমার অ্যাডাপ্টারে সমস্যাগুলি কাটিয়ে উঠতে হবে?


4
আপনার প্রশ্নের আমার প্রশ্নের উত্তর ছিল। +1
শশাঙ্ক দেবলুকার

উত্তর:


113

আমি কেবল এই সমস্যাটি জুড়ে এসেছি এবং সর্বোত্তম উপায়টি শিরোনামের সংস্করণ হিসাবে অ্যাকাউন্ট হিসাবে ListView.getItemAtPosition(position)পরিবর্তে ব্যবহার করার অর্থাত্: -ListAdapter.getItem(position)ListView

পরিবর্তে এটি করুন:

myListView.getItemAtPosition(position)

4
তাই ডান! onItemClickআপনাকে parentএকটি কারণ দেয় আপনি ব্যবহার করতে পারেনparent.getItemAtPosition(position)
ব্রাইস গাবিন

4
এটি আসলে আমার পক্ষে কাজ করেনি যেখানে @ ওয়ান্ড্রয়েড সজ্জিত / মোড়ক অ্যাডাপ্টার সমাধান ব্যবহার করে।
ডোরি

4
এছাড়াও আপনি এই ক্ষেত্রে আইটেম নিক্ষেপ করতে হবে।
njzk2

আমি পিতামাতাকে তালিকাভিউতে কাস্ট করলেও আমার পক্ষে কাজ করে না। আমার কেবল পজিশনটি বাতিল করতে হবে == 0 ...
পাভেলপ

আমার জন্য কাজ করে না। AdapterViewযোগ করা অ্যাডাপ্টার যোগ করা তালিকার নিচে কেবল যায়। return (adapter == null || position < 0) ? null : adapter.getItem(position);
ফিলিপ

31

আপনি যদি শিরোনামটিতে ক্লিকের বিষয়ে চিন্তা না করেন তবে আপনার অ্যাডাপ্টারের জন্য অবস্থানটি পেতে অবস্থান থেকে শিরোনামের সংখ্যার বিয়োগ করুন:

        listView.addHeaderView(inflater.inflate(
                R.layout.my_hdr_layout, null), null, false);
        listView.setAdapter(m_adapter);
        listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            position -= listView.getHeaderViewsCount();
            final MyObject object = m_adapter.getItem(position);

        }
    });

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

আমি মনে করি এই
sha

27

আপনি যদি একটি শিরোনাম যোগ ListViewকরেন যা তালিকার প্রথম আইটেম হয়ে যায়। আপনি অগ্রাহ্য করে এই ক্ষতিপূরণ পারে getCount()একটি আইটেম কম ফিরে যাওয়ার, কিন্তু আপনি হ্যান্ডেল নিশ্চিত getItem(), getItemId()ইত্যাদি হেডার অবস্থান 0 আইটেম হবে না।


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

4
তালিকার আইটেমিক্লিক সেট পজিশনে = অবস্থান - 1 যদি কোনও শিরোনাম সংযুক্ত থাকে তবে আমি মনে করি যে আমি যখন এই বিশেষ সমস্যাটির মুখোমুখি হয়েছিলাম তখন আমি কী করেছি, এটি খুব ঝরঝরে নয়, তবে কেবলমাত্র আমি ভাবতে পারি
অক্ষয়দশ্রথ

4
আমি অনুমান করি যে সবচেয়ে সহজ উপায় হ'ল আপনার পরামর্শ অনুসারে অনিআইটেমিক্লিকলাইজনারে পজিশন = পজিশন- (যুক্ত হেডরভিউগুলির সংখ্যা) স্থাপন করা। আমি হেডরভিউ নিজেই পরিচালনা করতে আমার অ্যাডাপ্টারটি পরিবর্তন করেছি, সুতরাং আমাকে তালিকার ভিউতে অ্যাডহাইডারভিউ কল করতে হবে না। যদিও অ্যাডাপ্টারটি আরও জটিল হয়েছিল।
d1rk

22
"যোগ করা হেডেরভিউগুলির সংখ্যা" এর সাথে পাওয়া যাবে:ListView.getHeaderViewsCount()
জন

4
আমি দেখতে পাচ্ছি না কিভাবে এটি সঠিক উত্তর। @ আইয়ান ওয়ারউইক সঠিক পোস্ট করেছেন, তবে আমি ধরে নিচ্ছি কিছুটা দেরি।
সিডন

14

বাস্তবায়ন করার সময় AdapterView.OnItemClickListenerআমরা অবস্থান থেকে কেবল শিরোনামকে বিয়োগ করি।

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    position -= mListView.getHeaderViewsCount();
    // what ever else follows...
}

13

কোনও কোড পরিবর্তন করার দরকার নেই। কেবল কোডের নীচে ব্যবহার করুন।

 list.setOnItemClickListener(new OnItemClickListener() {
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      parent.getAdapter().getItem(position);
         //Do something with it
     }
});

4
এটি সাধারণত কাস্টিংয়ের প্রয়োজন হবে, কারণ আইটেমটি ফিরিয়ে দেওয়া হচ্ছে কেবল "অবজেক্ট"।
অ্যান্ড্রয়েড বিকাশকারী

9

আপনার অ্যাডাপ্টার ব্যবহার করবেন না, getAdapter থেকে 'সজ্জিত' অ্যাডাপ্টার ব্যবহার করুন।


এই আইএমওটি +1 যাওয়ার উপায় - আপনার সরবরাহ করা অ্যাডাপ্টারটি অন্য অ্যাডাপ্টারের সাথে আবৃত হয় যা আপনি যখন শিরোনাম সরবরাহ করেন তখন সূচকটিকে অফসেট অ্যাকাউন্টে গ্রহণ করে। এটির জন্য এই কোডটি এটি ব্যবহার করছে @ রমেশ এই পৃষ্ঠায় অন্য কোথাও দিয়েছেন (+1 আপনাকেও!)
ডরি

5

এর একটি সমাধান হ'ল সূচকে আইডি ম্যাপ করা। মূলত আইডি তালিকাতে সূচক ফেরত করুন এবং ক্লিক শ্রোতারা করতে হবে:

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            listAdapter.getItem((int) id);
}

3

হাই, আমরা এটির সমাধান করতে পারি প্রথমে আপনি আপনার শিরোনামের দৃশ্য তৈরি করুন, আপনার তালিকায় ইনজেকশন দেওয়ার পরে এবং শেষ পদক্ষেপটি সেটঅনক্লিকলিস্টনারকে অক্ষম করে unable এটা আমার জন্য কাজ। কোন প্রতিক্রিয়া স্বাগত

ViewGroup headerView = (ViewGroup) getLayoutInflater().inflate(R.layout.your_header, list,false);
list.addHeaderView(headerView);
headerView.setEnabled(false);
headerView.setOnClickListener(null);

এটি উত্তরের তালিকার নিচে, তবে এটি সত্যই কার্যকর। আপনি যদি এই পরিবর্তনগুলি না করেন, তবে আপনার হেডার দর্শনটি রিপাল এফেক্টস ইত্যাদির সাথে ক্লিকযোগ্য থাকবে
স্কট ফার্গুসন

0

@ রমেশ যোগ করেন নি এমন নতুন কিছু যুক্ত করতে নয় তবে কিছু অতিরিক্ত প্রসঙ্গ:

personList.setOnItemClickListener(new OnItemClickListener() {
    @SuppressWarnings("unchecked")
    public void onItemClick( AdapterView<?> parent, View view, int position, long duration) {
        Map<String, Object> person = (Map<String, Object>) parent.getAdapter().getItem(position);
        if (person != null){

            // If the header was clicked on a null  is returned

            OnPersonUiChangeListener listener = (OnPersonUiChangeListener) getActivity();
            listener.onSelectedPersonChanged(person);
        }
    }
});

0

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


0

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

        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
        position += 1;
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        position -= 1;
        setTitle(mNavigationDrawerItemTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.