একটি অ্যান্ড্রয়েড স্পিনারে কীভাবে একটি আইটেম লুকানো যায়


101

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

স্ট্যাকওভারফ্লোতে আইটেমগুলি কীভাবে অক্ষম (গ্রে আউট) করা যায় তার জন্য কিছু কোড রয়েছে তবে কীভাবে আইটেমগুলির অস্তিত্ব নেই তা সম্পূর্ণরূপে আড়াল করবেন কীভাবে তা নয়।

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

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

অ্যারেএডাপ্টার পদ্ধতি ওভাররাইড সহ স্পিনার সেটআপ উদাহরণ:

List<String> list = new ArrayList<String>();
list.add("");   //  Initial dummy entry
list.add("string1");
list.add("string2");
list.add("string3");

// Populate the spinner using a customized ArrayAdapter that hides the first (dummy) entry
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, list) {
    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent)
    {
        View v = null;

        // If this is the initial dummy entry, make it hidden
        if (position == 0) {
            TextView tv = new TextView(getContext());
            tv.setHeight(0);
            tv.setVisibility(View.GONE);
            v = tv;
        }
        else {
            // Pass convertView as null to prevent reuse of special case views
            v = super.getDropDownView(position, null, parent);
        }

        // Hide scroll bar because it appears sometimes unnecessarily, this does not prevent scrolling 
        parent.setVerticalScrollBarEnabled(false);
        return v;
    }
};

dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(dataAdapter);

আপনি অন্যান্য interwebs কি খুঁজে পেয়েছেন? আপনি এ পর্যন্ত কি কি?
dldnh

দুঃখিত লাহ, আমি কীভাবে করব জানি না।
লুইস্ট

চমৎকার সমাধান! তবে আমি মনে করি tv.setVisibility(View.GONE);লাইনটি অপ্রয়োজনীয়। এটির মন্তব্য করা কোনও (ভিজ্যুয়াল) পার্থক্য বলে মনে হচ্ছে না, কমপক্ষে অ্যান্ড্রয়েড ৪.৪.২ / কিটকিট (কোনও এলজি / গুগল নেক্সাস ৪ এ)।
ম্যাথিয়াস

এই প্রশ্নের উত্তরটি ভাল কাজ করে ..
ইঁদুর-এ-ট্যাট-এ-ট্যাট রাতাতুইল

এটি কোনও উন্নতি নাও হতে পারে তবে আমি setTag(1)0 অবস্থানের টেক্সটভিউতে ব্যবহার করেছি, তারপরে convertView.getTag() != nullপুনরায় ব্যবহৃত ভিউ 0 পজিশনের জন্য তৈরি 0 উচ্চতার ভিউ বা অন্য স্পিনার আইটেমগুলির জন্য ব্যবহৃত একটি সাধারণ ভিউ কিনা তা নির্ধারণ করতে ব্যবহৃত হত। এটি এমন ছিল যাতে আমি super.getDropDownView(position, convertView, parent)সবসময় নতুন ভিউ তৈরির পরিবর্তে কখনও কখনও ব্যবহার করতে পারি ।
ড্যানিয়েল হ্যান্ডোজো

উত্তর:


49

একটি স্বেচ্ছাসেবী আইটেম বা একাধিক আইটেম লুকানোর জন্য আমি মনে করি আপনি নিজের অ্যাডাপ্টারটি প্রয়োগ করতে পারেন এবং যে তালিকাটি লুকিয়ে রাখতে চান তা সূচক (বা সূচকের অ্যারে তালিকা) সেট করতে পারেন।

public class CustomAdapter extends ArrayAdapter<String> {

     private int hidingItemIndex;

     public CustomAdapter(Context context, int textViewResourceId, String[] objects, int hidingItemIndex) {
         super(context, textViewResourceId, objects);
         this.hidingItemIndex = hidingItemIndex;
     }

     @Override
     public View getDropDownView(int position, View convertView, ViewGroup parent) {
         View v = null;
         if (position == hidingItemIndex) {
             TextView tv = new TextView(getContext());
             tv.setVisibility(View.GONE);
             v = tv;
         } else {
             v = super.getDropDownView(position, null, parent);
         }
         return v;
     }
 }

আপনি আইটেমের তালিকা তৈরি করার সময় আপনার কাস্টম অ্যাডাপ্টার ব্যবহার করুন।

List<String> list = new ArrayList<String>();
list.add("");   //  Initial dummy entry
list.add("string1");
list.add("string2");
list.add("string3");

int hidingItemIndex = 0;

CustomAdapter dataAdapter = new CustomAdapter(this, android.R.layout.simple_spinner_item, list, hidingItemIndex);

dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(dataAdapter);

(আমি কোডটি পরীক্ষা করি নি) আশা করি যা সহায়তা করে।


1
এটি কোনও সমাধান নয়। প্রশ্নের আপডেটটি সঠিক কোড সরবরাহ করে।
dldnh

13
টিভি.সেটহাইট (0) ছাড়া টেক্সটভিউটি এখনও দৃশ্যমান।
v4r

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

1
অসাধারণ :) সহজ সমাধান :)
চৈতন্য

1
একটি যাদুমন্ত্র মত কাজ করে..!
কৃপা কাক্কাদ

20

তালিকার শেষে তালিকার শেষে কোনও আইটেমটি আড়াল করা সহজ।

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

List<String> list = new ArrayList<String>();
list.add("string1");
list.add("string2");
list.add("string3");
list.add("[Select one]");
final int listsize = list.size() - 1;

ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, list) {
    @Override
    public int getCount() {
        return(listsize); // Truncate the list
    }
};

dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(dataAdapter);
mySpinner.setSelection(listsize); // Hidden item to appear in the spinner

3
আমি একটি পরিষ্কার পদ্ধতির সন্ধানের জন্য অর্ধ ঘন্টা অনুসন্ধান করছিলাম এবং এটি এখন পর্যন্ত সর্বোত্তম পন্থা। কেবল তালিকাটি কেটে ফেলুন তবে আইটেমটি আসলে বিদ্যমান। দুর্দান্ত।
কেএসদেব

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

1
ওরিয়েন্টেশন পরিবর্তনে স্পিনার পাঠ্যটি 'স্ট্রিং 3' তে পরিবর্তিত হয় এমনকি স্পিনারও অচ্ছুত থাকে। @ রোমিচ
ইয়ক্ষ

আমার প্রশ্ন কেউ কি দেখতে পারেন ?
মোয়েজ

5

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

public class CustomAdapter extends ArrayAdapter<String> {

private List<String> dates;
private int hideItemPostion;

public CustomAdapter (Context context, int resource, List<String> dates) {
    super(context, resource,dates);
    this.dates=dates;
}
public void setItemToHide(int itemToHide)
{
    this.hideItemPostion =itemToHide;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
    View v = null;
    if (position == hideItemPostion) {
        TextView tv = new TextView(getContext());
        tv.setVisibility(View.GONE);
        tv.setHeight(0);
        v = tv;
        v.setVisibility(View.GONE);
    }
    else
        v = super.getDropDownView(position, null, parent);
    return v;
}}

এবং অ্যাডাপ্টার সেট এই রকম কিছু

final CustomAdapter dataAdapter = new CustomAdapter(this,R.layout.spinner_item,dates);
    dataAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
    spinner.setAdapter(dataAdapter);
    dataAdapter.setItemToHide(0);

ড্রপডাউন থেকে কিছু আইটেম নির্বাচন করার সময়ও অবস্থান পরিবর্তন করা দরকার

 spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, final int i, long l) {
        dataAdapter.notifyDataSetChanged();
            mEPGDateSelector.setSelection(i);
            dataAdapter.setItemToHide(i);}

             @Override
        public void onNothingSelected(AdapterView<?> adapterView) {

        }
    });

1

কেবল আগ্রহের জন্য, আমি একটি ইঙ্গিত হিসাবে "প্রম্পট" ব্যবহার করার জন্য একটি সমাধান করেছি। এই কোডটি তৈরি করা হয়েছে Xamarin.Android, তবে এটি 10 ​​মিনিটের মধ্যে পুরোপুরি জাভাতে পোর্ট করা যেতে পারে। ArrayAdapterসোর্স অ্যারেতে 0-ইনডেক্সড বা কাউন্ট-ইনডেক্সড আইটেমগুলি যুক্ত না করে সাধারণের মতো এটি ব্যবহার করুন । SpinnerGeolocation.SelectedItemIdকিছুই -1 ( hintবর্তমান আইটেমটি) চয়ন না করা হলে এটি -1 এও সেট করে ।

public class ArrayAdapterWithHint<T>: ArrayAdapter<T>
{
    protected bool HintIsSet = false;
    protected int HintResource = 0;

    public ArrayAdapterWithHint(Context context, int textViewResourceId,
                   T[] objects)
        : base(context, textViewResourceId, objects)
    {
    }
    public ArrayAdapterWithHint(Context context, int hintResource,
                   int textViewResourceId, T[] objects)
        : base(context, textViewResourceId, objects)
    {
        HintResource = hintResource;
    }
    public ArrayAdapterWithHint(Context context, int textViewResourceId,
             IList<T> objects)
        : base(context, textViewResourceId, objects)
    {
    }
    public ArrayAdapterWithHint(Context context, int hintResource,
                    int textViewResourceId, IList<T> objects)
        : base(context, textViewResourceId, objects)
    {
        HintResource = hintResource;
    }

    public override View GetDropDownView(int position, View convertView,
                ViewGroup parent)
    {
        if (HintIsSet)
            return base.GetDropDownView(position + 1,
                               convertView, parent);
        return base.GetDropDownView(position, convertView, parent);
    }

    public override View GetView(int position, View convertView,
                      ViewGroup parent)
    {
        if (!HintIsSet && parent is Spinner && 
                    !string.IsNullOrWhiteSpace((parent as Spinner).Prompt))
        {
            Insert((parent as Spinner).Prompt, 0);
            HintIsSet = true;
            (parent as Spinner).SetSelection(base.Count - 1);
        }
        if (HintIsSet && position >= base.Count - 1)
        {
            View hintView = base.GetView(0, convertView, parent);
            if (hintView is TextView)
                (hintView as TextView).SetTextAppearance(
                                                     Context, HintResource);
            return hintView;
        }
        if (HintIsSet && position < base.Count - 1)
            return base.GetView(position + 1, convertView, parent);
        return base.GetView(position, convertView, parent);
    }

    public override long GetItemId(int position)
    {
        if (HintIsSet)
        {
            if (position >= base.Count - 1)
                return -1;
            return position;
        }
        return base.GetItemId(position);
    }

    public override int Count
    {
        get
        {
            return base.Count > 0 && HintIsSet ? base.Count - 1 : base.Count;
        }
    }
}

আমার প্রশ্ন কেউ কি দেখতে পারেন ?
মোয়েজ

1

আমি এই সমাধানটি পেয়েছি যা আমার সমস্যার সমাধান করেছে।

final Spinner mySpinner = (Spinner)findViewById(R.id.spinner_triptype);

   final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.spinner_item, R.id.weekofday, triptype_initial);

   final ArrayAdapter<String> adapter_temp = new ArrayAdapter<String>
(this,R.layout.spinner_item, R.id.weekofday, triptype_array);


   mySpinner.setAdapter(adapter);
    mySpinner.setOnTouchListener(new View.OnTouchListener() {
       @Override
       public boolean onTouch(View v, MotionEvent event) {
       // display your error popup here
        if(flag_spinner_isFirst){
           mySpinner.setAdapter(adapter_temp);
           flag_spinner_isFirst = false;
          }
           v.onTouchEvent(event);
           return true;

       }
    });

0

আমি মনে করি স্পিনারের পরিবর্তে অ্যারে তালিকায় বৈধতা দেওয়া ভাল হবে কারণ একবার আইটেমটি ফিল্টার হয়ে গেলে স্পিনারে যুক্ত করা নিরাপদ হবে


0

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

আপনার অ্যাডাপ্টারের ক্লাস প্রসারিত তৈরি করুন ArrayAdapter

আপনার পদ্ধতির ভিতরে

public View getView(int position, View convertView, ViewGroup parent) {
    View row = getCustomView();
    if(position==0) // put the desired check here.
         {
            row  = new View(context);
         }
    }
    return row;
}

0

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

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

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

class ArrayAdapterCustom(context: Context, textViewResourceId: Int, vararg objects: String)
    : ArrayAdapter<String>(context, textViewResourceId, objects) {

    //Can skip first n items (skip 1 as default)
    var hideFirstItemsCount = 1

    override fun getCount(): Int {
        return super.getCount() - hideFirstItemsCount
    }

    override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
        return super.getDropDownView(position + hideFirstItemsCount, convertView, parent)
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.