অ্যান্ড্রয়েড: একাধিক ক্লিকযোগ্য বোতামগুলির সাথে তালিকাভুক্ত উপাদানগুলি


182

আমি এমন একটি ListViewযেখানে তালিকার প্রতিটি উপাদানটিতে একটি পাঠ্য ভিউ এবং দুটি পৃথক বোতাম রয়েছে। এটার মতো কিছু:

ListView
--------------------
[Text]
[Button 1][Button 2]
--------------------
[Text]
[Button 1][Button 2]
--------------------
... (and so on) ...

এই কোড দিয়ে আমি OnItemClickListenerপুরো আইটেমটির জন্য একটি তৈরি করতে পারি :

listView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> list, View view, int position, long id) {
        Log.i(TAG, "onListItemClick: " + position);

        }

    }
});

তবে, আমি চাই না যে পুরো আইটেমটি ক্লিকযোগ্য হয়ে উঠুক, তবে প্রতিটি তালিকার উপাদানগুলির দুটি মাত্র বোতাম।

সুতরাং আমার প্রশ্নটি হল, আমি কীভাবে নিম্নলিখিত প্যারামিটারগুলি সহ এই দুটি বোতামের জন্য একটি অন্লিকলিস্টাইনার প্রয়োগ করব:

  • int button (উপাদানটির কোন বোতামটি ক্লিক করা হয়েছে)
  • int position (তালিকার যে উপাদানটির উপর বোতামটি ক্লিক হয়েছে)

আপডেট: নীচে আমার উত্তরে বর্ণিত সমাধান পেয়েছি। এখন আমি টাচ স্ক্রিনের মাধ্যমে বোতামটি ক্লিক / ট্যাপ করতে পারি। তবে আমি ট্র্যাকবল দিয়ে ম্যানুয়ালি এটি নির্বাচন করতে পারি না। এটি সর্বদা পুরো তালিকা আইটেমটি নির্বাচন করে এবং সেখান থেকে সরাসরি পরবর্তী তালিকার আইটেমে যায় বোতামগুলি উপেক্ষা করে, যদিও আমি সেট করেছিলাম .setFocusable(true)এবং setClickable(true)বোতামগুলির জন্য getView()

আমি আমার কাস্টম তালিকা অ্যাডাপ্টারে এই কোডটি যুক্ত করেছি:

@Override
public boolean  areAllItemsEnabled() {
    return false;           
}

@Override
public boolean isEnabled(int position) {
        return false;
}

এর ফলে কোনও তালিকার আইটেম আর কোনওটিতে নির্বাচনযোগ্য নয়। তবে এটি নেস্টেড বোতামগুলি নির্বাচনযোগ্য করে তুলতে সহায়তা করে নি।

কেউ ধারণা?


এগুলি কি এখনও দরকার?
স্টুয়ার্ট অ্যাকসন

আপনি যদি বেসএডাপ্টার কোডটি দেখেন তবে আপনি দেখতে পাবেন যে areAllItemsEnabled () এবং isEn सक्षम () কেবলমাত্র হার্ডকোড করা হয়েছে, এগুলি কোনও যুক্তি ছাড়াই সাধারণ স্থানধারক তৈরি করে।
আর্টেম রাশাকোভস্কি

আমি যদি সিম্পলসার্সার অ্যাডাপ্টার ব্যবহার করতে চাই তবে কি আমাকে কি কাস্টম অ্যাডাপ্টারটি সরলসারসোরডাপ্টার প্রসারিত করতে হবে?
ওরটিস

উত্তর:


150

এর সমাধানটি আমি যা ভাবি তার চেয়ে সহজতর। আপনি যে কাস্টম অ্যাডাপ্টারের getView()পদ্ধতিটি ব্যবহার করছেন তার জন্য আপনি একটি সেটঅনক্লিকলিস্টার () যোগ করতে পারেন ।

বাটন সঙ্গে সম্পর্কিত কোন তথ্য দিয়ে জুড়তে হবে myButton.setTag()মধ্যে getView()এবং মাধ্যমে onClickListener মধ্যে অ্যাক্সেস করা যেতে পারেview.getTag()

আমি আমার ব্লগে একটি টিউটোরিয়াল হিসাবে একটি বিস্তারিত সমাধান পোস্ট করেছি


2
সংশোধন করা হয়েছে। প্রতিবেদনের জন্য ধন্যবাদ :-)
znq

আপনি কোয়েরি থেকে কতটা তাত্ক্ষণিকভাবে curItem.url পেয়েছেন, আপনি কি আরও নির্দিষ্ট বলবেন?
ওরটিস

1
ধন্যবাদ জেডএনকিউ, এটি আমার পক্ষে খুব কার্যকর ছিল ... সময়ের একটি বান্ডিল সংরক্ষণ করা হয়েছিল।
নন্দগোপাল টি

এই আলোচনাটি 11:39 এ দেখুন একটি দুর্দান্ত উদাহরণ রয়েছে: youtu.be/wDBM6wVEO70?t=11m39s তারপরে @znq যা বলেছে তা করুন ... সেটক্যাগ () যখন কনভার্টভিউ == নালু হয়ে যান এবং অনক্লিক () এ getTag () করুন বোতামের ক্লিকক্লিক্লিশনার পদ্ধতি ()। ধন্যবাদ!
শেহাজ

12
নিজে থেকেই উত্তরগুলি পাওয়া এবং অন্য কোনও পৃষ্ঠাতে নির্দেশ না করাই দুর্দান্ত হবে। ব্লগ লিঙ্কটি মারা গেছে!
gsb

63

এটি @ znq এর উত্তরের একটি সংযোজন ...

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

আপনি নিম্নলিখিত কাস্টম অ্যাডাপ্টার দিয়ে এটি করতে পারেন:

private static class CustomCursorAdapter extends CursorAdapter {

    protected ListView mListView;

    protected static class RowViewHolder {
        public TextView mTitle;
        public TextView mText;
    }

    public CustomCursorAdapter(Activity activity) {
        super();
        mListView = activity.getListView();
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        // do what you need to do
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View view = View.inflate(context, R.layout.row_layout, null);

        RowViewHolder holder = new RowViewHolder();
        holder.mTitle = (TextView) view.findViewById(R.id.Title);
        holder.mText = (TextView) view.findViewById(R.id.Text);

        holder.mTitle.setOnClickListener(mOnTitleClickListener);
        holder.mText.setOnClickListener(mOnTextClickListener);

        view.setTag(holder);

        return view;
    }

    private OnClickListener mOnTitleClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            final int position = mListView.getPositionForView((View) v.getParent());
            Log.v(TAG, "Title clicked, row %d", position);
        }
    };

    private OnClickListener mOnTextClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            final int position = mListView.getPositionForView((View) v.getParent());
            Log.v(TAG, "Text clicked, row %d", position);
        }
    };
}

6
অথবা আপনি এই তালিকাভিউ এমলিস্টভিউ = (লিস্টভিউ) v.getParent ()। getParent ();
সর্বোচ্চ

1
আমি যদি পৃথক শ্রেণিতে অ্যাডাপ্টার ব্যবহার করি তবে আমি কীভাবে অবস্থান পেতে পারি। আমি অনিক্লিকলিস্টারের অভ্যন্তরে কেবল পজিশনটি ব্যবহার করেছি, এই জাতীয়_সি.জেটের মতো (অবস্থান) something এটি অ্যাডাপ্টারের getView পদ্ধতিতে অবস্থান চূড়ান্ত করার পরামর্শ দেয়। যদি আমি সেই অবস্থানটি পরিবর্তন করি তবে আমি যে পজিশন পেয়েছি তা লিসভিউয়ের সমস্ত আইটেমের জন্য একই। আপনি কি আমাকে এটি সমাধান করতে পরামর্শ দিতে পারেন?
মানিকান্দন

কারণ আপনি যখন ভিউ পদ্ধতির অবস্থানের প্যারামিটারটি ব্যবহার করেন এটি আপনাকে তালিকার আইটেমটির অবস্থান দেয় যা আপনি সম্প্রতি তৈরি করেছেন তবে আপনি যে ক্লিক
করেননি

@ মানিকান্দন: আপনি যদি অ্যাডাপ্টারের গেটভিউ () পদ্ধতিটি ব্যবহার করে থাকেন তবে আপনার ইতিমধ্যে পদ্ধতিটি প্যারামে আপনার কাছে অবস্থানটি উত্তীর্ণ হয়েছে। সেক্ষেত্রে আপনি অবস্থানের তথ্য সঞ্চয় করতে সেটট্যাগ () এর মতো কিছু ব্যবহার করতে পারেন।
গ্রেগ 7gkb

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

22

ভবিষ্যতের পাঠকদের জন্য:

ট্র্যাকবল ব্যবহারের সাথে বোতামগুলি ম্যানুয়ালি নির্বাচন করতে:

myListView.setItemsCanFocus(true);

এবং পুরো তালিকা আইটেমগুলিতে ফোকাস অক্ষম করতে:

myListView.setFocusable(false);
myListView.setFocusableInTouchMode(false);
myListView.setClickable(false);

এটি আমার পক্ষে দুর্দান্ত কাজ করে, আমি টাচস্ক্রিনযুক্ত বোতামগুলিতে ক্লিক করতে পারি এবং কীপ্যাড ব্যবহার করে একটি ক্লিক ফোকাস করতে পারি


2
এই একজনই আমাকে সাহায্য করেছেন! আপনাকে অনেক ধন্যবাদ!
ওনুর

এক্সপেন্ডেবললিস্টভিউ সম্পর্কে কী, আইটেমটিতে আমার একাধিক মতামত রয়েছে, আমি কেবলমাত্র শিশুটিকে ক্লিকযোগ্যযোগ্য মতামতগুলিতে চাই, ধন্যবাদ।
twlkyao

12

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

<Button
        android:id="@+id/btnRemove"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/btnEdit"
        android:layout_weight="1"
        android:background="@drawable/btn"
        android:text="@string/remove" 
        android:onClick="btnRemoveClick"
        />

বিটিএনআরমোভ ক্লিক ক্লিক ইভেন্ট

public void btnRemoveClick(View v)
{
    final int position = listviewItem.getPositionForView((View) v.getParent()); 
    listItem.remove(position);
    ItemAdapter.notifyDataSetChanged();

}

আকর্ষণীয় সমাধান
শেরপ্যা

9

সম্ভবত আপনি এটি কীভাবে করবেন তা খুঁজে পেয়েছেন তবে আপনি কল করতে পারেন

ListView.setItemsCanFocus(true)

এবং এখন আপনার বোতাম ফোকাস ধরা হবে


5

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

package br.com.fontolan.pessoas.arrayadapter;

import java.util.List;

import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import br.com.fontolan.pessoas.R;
import br.com.fontolan.pessoas.model.Telefone;

public class TelefoneArrayAdapter extends ArrayAdapter<Telefone> {

private TelefoneArrayAdapter telefoneArrayAdapter = null;
private Context context;
private EditText tipoEditText = null;
private EditText telefoneEditText = null;
private ImageView deleteImageView = null;

public TelefoneArrayAdapter(Context context, List<Telefone> values) {
    super(context, R.layout.telefone_form, values);
    this.telefoneArrayAdapter = this;
    this.context = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.telefone_form, parent, false);

    tipoEditText = (EditText) view.findViewById(R.id.telefone_form_tipo);
    telefoneEditText = (EditText) view.findViewById(R.id.telefone_form_telefone);
    deleteImageView = (ImageView) view.findViewById(R.id.telefone_form_delete_image);

    final int i = position;
    final Telefone telefone = this.getItem(position);
    tipoEditText.setText(telefone.getTipo());
    telefoneEditText.setText(telefone.getTelefone());

    TextWatcher tipoTextWatcher = new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void afterTextChanged(Editable s) {
            telefoneArrayAdapter.getItem(i).setTipo(s.toString());
            telefoneArrayAdapter.getItem(i).setIsDirty(true);
        }
    };

    TextWatcher telefoneTextWatcher = new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void afterTextChanged(Editable s) {
            telefoneArrayAdapter.getItem(i).setTelefone(s.toString());
            telefoneArrayAdapter.getItem(i).setIsDirty(true);
        }
    };

    tipoEditText.addTextChangedListener(tipoTextWatcher);
    telefoneEditText.addTextChangedListener(telefoneTextWatcher);

    deleteImageView.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            telefoneArrayAdapter.remove(telefone);
        }
    });

    return view;
}

}

3

আমি জানি এটি দেরি হয়ে গেছে তবে এটি সাহায্য করতে পারে, এটি বিভিন্ন উদাহরণের জন্য আমি কীভাবে কাস্টম অ্যাডাপ্টারের ক্লাস লিখি class

 public class CustomAdapter extends BaseAdapter {

    TextView title;
  Button button1,button2;

    public long getItemId(int position) {
        return position;
    }

    public int getCount() {
        return mAlBasicItemsnav.size();  // size of your list array
    }

    public Object getItem(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            convertView = getLayoutInflater().inflate(R.layout.listnavsub_layout, null, false); // use sublayout which you want to inflate in your each list item
        }

        title = (TextView) convertView.findViewById(R.id.textViewnav); // see you have to find id by using convertView.findViewById 
        title.setText(mAlBasicItemsnav.get(position));
      button1=(Button) convertView.findViewById(R.id.button1);
      button1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //your click action 

           // if you have different click action at different positions then
            if(position==0)
              {
                       //click action of 1st list item on button click
        }
           if(position==1)
              {
                       //click action of 2st list item on button click
        }
    });

 // similarly for button 2

   button2=(Button) convertView.findViewById(R.id.button2);
      button2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //your click action 

    });



        return convertView;
    }
}

-4

এই বাস্তবায়নের জন্য প্ল্যাটফর্ম সমাধানটি কি একটি দীর্ঘ প্রেসে প্রদর্শিত একটি প্রসঙ্গ মেনু ব্যবহার করার জন্য নয়?

প্রশ্ন লেখক প্রসঙ্গে মেনু সম্পর্কে সচেতন? একটি লিস্টভিউতে বোতামগুলি সজ্জিতকরণের কার্যকারিতা জড়িত রয়েছে, আপনার ইউআইকে বিশৃঙ্খলা করবে এবং প্ল্যাটফর্মের জন্য প্রস্তাবিত ইউআই নকশা লঙ্ঘন করবে।

উল্টানো দিকে; প্রসঙ্গের মেনুগুলি - প্যাসিভ উপস্থাপনা না করার স্বভাব অনুসারে - শেষ ব্যবহারকারীর কাছে সুস্পষ্ট নয়। আচরণ নথিভুক্ত বিবেচনা?

এই গাইড আপনাকে একটি ভাল শুরু করা উচিত।

http://www.mikeplate.com/2010/01/21/show-a-context-menu-for-long-clicks-in-an-android-listview/

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