MenuItemCompat.getActionView সর্বদা শূন্য দেয়


142

আমি সবেমাত্র বাস্তবায়ন করেছি v7 AppCompat সমর্থন লাইব্রেরি তবে MenuItemCompat.getActionViewআমি পরীক্ষিত প্রতিটি অ্যান্ড্রয়েড সংস্করণে সর্বদা বাতিল হয়ে যায় (৪.২.২, ২.৩.৪ ....)

SearchViewকর্ম বার প্রদর্শন করা হয় কিন্তু এটি ক্রিয়া স্পর্শ সাড়া না এবং দেখানোর জন্য প্রসারিত না তার EditTextএবং শুধুমাত্র একটি সহজ আইকন ভালো হয়।

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu, menu);

    MenuItem searchItem = menu.findItem(R.id.action_search);
    SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
    if (searchView != null) {
        SearchViewCompat.setOnQueryTextListener(searchView, mOnQueryTextListener);
        searchView.setIconifiedByDefault(false);
        Log.d(TAG,"SearchView not null");
    } else
        Log.d(TAG, "SearchView is null");
    }
    return super.onCreateOptionsMenu(menu);
}

Menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">

    <item android:id="@+id/action_search"
          app:showAsAction="always|collapseActionView"
          android:icon="@drawable/abc_ic_search"
          android:title="@string/action_bar_search"
          android:actionViewClass="android.support.v7.widget.SearchView"/>

    <item android:id="@+id/action_refresh"
          android:icon="@drawable/refresh"
          android:title="@string/action_bar_refresh"
          app:showAsAction="ifRoom"/>
</menu>

উত্তর:


296

অবশেষে আমি সমাধানটি খুঁজে পেলাম।

  1. এর নামস্থান পরিবর্তন actionViewClassথেকে android:actionViewClassথেকেapp:actionViewClass

  2. বাস্তবায়নকারী android.support.v7.widget.SearchView.OnQueryTextListenerবর্তমান কার্যকলাপের জন্য ইন্টারফেস।

  3. সরাসরি setOnQueryTextListenerপরিবর্তে ব্যবহার করুনSearchViewCompat.setOnQueryTextListener

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
      MenuInflater inflater = getMenuInflater();
      inflater.inflate(R.menu.menu, menu);
    
      MenuItem searchItem = menu.findItem(R.id.action_search);
      SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
      if (searchView != null) {
         searchView.setOnQueryTextListener(this);
      }
    
      return super.onCreateOptionsMenu(menu);
    }

3
যদি এটি আপনার সমস্যার সমাধান করে তবে আপনার সম্ভবত উত্তরটি গ্রহণ করা উচিত। আমি একই ধরণের সমস্যাযুক্ত অন্য সমস্ত লোককে একই ধরণের সমস্যা নিয়ে আরও একটি থ্রেডের দিকে ইঙ্গিত করতে চাই: স্ট্যাকওভারফ্লো . com / q / 18407171 / 1108032 । যদি বর্তমান থ্রেড আপনার সমস্যাগুলি সমাধান না করে, তবে সেগুলির সমাধানগুলি অনুসন্ধান করার বিষয়টি বিবেচনা করুন।
বরিস স্ট্রান্ডজেভ

4
দুর্দান্ত উত্তর! অ্যাপ্লিকেশনটিতে থাকা "অ্যাপ্লিকেশন": এটিকে স্পষ্ট করে দেওয়ার জন্য এটি অর্থ প্রদান করতে পারে: অ্যাকশনভিউক্ল্যাশসে "অ্যাপ্লিকেশন" নামের জায়গার জন্য অতিরিক্ত এক্সএমএলএনস ঘোষণাও প্রয়োজন।
jklp

3
বলা দরকার যে android.support.v7.widget.SearchViewক্লাসটি 'android.support.v4.widget.SearchViewCompat' শ্রেণীর সাথে বিভ্রান্ত হওয়া উচিত নয় (যা অ্যাকশনবারকপ্যাট লাইব্রেরি ব্যবহার করার সময় একটি সাধারণ ভুল হিসাবে পরিচিত)
অ্যালেক্স সেমেনিয়ুক

1
@jklp আমি xmlns ঘোষণা যোগ করার জন্য চেষ্টা <menu xmlns:app="http://schemas.android.com/apk/res/android" >কিন্তু ভুল পান Attribute is missing the Android namespace prefix। আপনি এটি পেয়েছেন, এবং আপনি এটি কীভাবে ঠিক করবেন?
anticafe

5
এছাড়াও নোট করুন, অ্যান্ড্রয়েড: শোঅ্যাকশনটি অ্যাপটিতেও প্রদর্শন করা দরকার: শোঅ্যাকশনও। এছাড়াও নিশ্চিত করুন যে ক্রিয়াকলাপের জন্য আপনার থিমটি (কেবল অ্যাপ্লিকেশন নয়) কোনও অ্যাপকম্প্যাট থিম উল্লেখ করছে। শেষ কথা, অ্যাপটির ঘোষণাটি হ'ল " স্কিমাস.অ্যান্ড্রয়েড.com
apk

85

আমার ক্ষেত্রে এটি প্রোগার্ড ফাইল ছিল। আপনার এই লাইনটি যুক্ত করতে হবে:

-keep class android.support.v7.widget.SearchView { *; }

2
বাহ, এই জিনিস কেন? এটিই ছিল আমার জন্য একমাত্র কাজ।
ক্লড

2
+1 টি। খুব সুস্পষ্ট, তবে আমি এখনও উল্লেখ করব - আপনি যদি সন্ধান ভিউকে অন্য শ্রেণিতে প্রসারিত করেছেন তবে সেই শ্রেণীর পথে অগ্রসর হতে হবে!
ব্যবহারকারী 2520215

42

আমার জন্য, একটি ভুল menu.xml নেমস্পেস আমদানি এই সমস্যার কারণ হয়েছে।

আমার মূল menu.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/tools">
        <item android:id="@+id/action_search"
              android:title="@string/map_option_search"
              android:icon="@drawable/ic_action_search"
              app:showAsAction="collapseActionView|ifRoom"
              app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>

দেখে মনে হচ্ছে এটি ফিরে xmlns:app="http://schemas.android.com/tools"আসছিল । এই আমদানিতে পরিবর্তন করা হচ্ছেMenuItemCompat.getActionView()nullxmlns:app="http://schemas.android.com/apk/res-auto"সমস্যাটি স্থির ।

নতুন কাজ menu.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
       <item android:id="@+id/action_search"
              android:title="@string/map_option_search"
              android:icon="@drawable/ic_action_search"
              app:showAsAction="collapseActionView|ifRoom"
              app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>

5

আমি মনে করি যে সমস্যাটি হ'ল আপনি সমর্থন ভি 7 প্যাকেজ থেকে অনুসন্ধান ভিউ ব্যবহার করেন এবং আপনার এপিআই স্তরটি ..... 22% তে সেট করা আছে?

সমস্যার সমাধানের জন্য আপনার কোডটি নিম্নলিখিতটিতে পরিবর্তন করা:

menu.xml

<?xml version="1.0" encoding="UTF-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item 
        android:id="@+id/action_search"
        android:icon="@drawable/actionbar_button_search"
        android:title="Search"
        android:showAsAction="always"
        android:actionViewClass="android.widget.SearchView" />
</menu> 

1
আপনি কী কোড নমুনা সরবরাহ করেছেন তা সমস্যার সমাধান করতে পারে তা আপনি ব্যাখ্যা করতে পারেন? (আমি ধরে নিলাম এটি করি))
এডগার এন

4

আমি একই ত্রুটির সাথে ছিলাম, আমার পদ্ধতিটি getActionView()সর্বদা শূন্য ছিল। সুতরাং, আমি নিম্নলিখিত জিনিসগুলি তৈরি করেছি:

<item android:id="@+id/action_search"
      android:icon="@drawable/abc_ic_search"
      android:title="@string/search_title"
      android:showAsAction="always"
      android:actionViewClass="android.widget.SearchView"/>

আমি কিছু পোস্টে দেখেছি যে লোকেরা অ্যাপটি ব্যবহার করছে: বা ইউর্যাপ, তবে আমি সাধারণত ব্যবহার করেছি android:ActionVewClass

আমার onCreateOptionsMenuপদ্ধতিতে:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.feed, menu);

    // Associate searchable configuration with the SearchView
    SearchManager searchManager = 
        (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.action_search)
            .getActionView();
    searchView.setSearchableInfo(searchManager
            .getSearchableInfo(getComponentName()));

    return true;
}

এবং onCreateপদ্ধতিতে রাখতে ভুলবেন না :

// enabling action bar app icon and behaving it as toggle button
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);

এটা আমার কার্যকলাপের জন্য "ব্যাপ্ত" জন্য খুব ভাল কাজ করে FragmentActivityএবং ActionBarActivity


2

উপরের মোহসেন আফশিনের উত্তরটি আমার সূচনা পয়েন্ট ছিল এবং আমি আমার সেটআপটি দিয়ে এটি কাজ করার জন্য কিছু টুইট করেছি:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu, menu);
    MenuItem searchItem = menu.findItem(R.id.action_search);
    // SearchView searchView = (SearchView) MenuItemCompat
    //    .getActionView(searchItem);
    SearchView searchView = (SearchView) searchItem.getActionView();
    if (searchView != null) {
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {
                // do something with s, the entered string
                query = s;
                Toast.makeText(getApplicationContext(), 
                    "String entered is " + s, Toast.LENGTH_SHORT).show();
                return true;
            }
            @Override
            public boolean onQueryTextChange(String s) {
                return false;
            }
        });
    }
    return super.onCreateOptionsMenu(menu);
}

menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity" >

<item android:id="@+id/action_search"
    android:orderInCategory="5"
    android:title="Search"
    android:icon="@drawable/ic_action_search"
    android:showAsAction="ifRoom|collapseActionView"
    android:actionViewClass="android.widget.SearchView" />
</menu>

1

আমার একই কোড ছিল তবে আমদানিটি ব্যবহার করার পরিবর্তে android.support.v7.widget.SearchView;আমি ব্যবহার করছিলাম import android.widget.SearchView;। এটি nullমান নিয়ে আমার সমস্যা সমাধান করেছে । সুতরাং আপনার অনুসন্ধান ক্রিয়াকলাপে এই কোডটি পরিবর্তন করুন এবং এটি কাজ করবে এবং এক্সএমএল ফাইলের নামস্থানও পরিবর্তন করবে।


এটি আমাদের সমস্যা ছিল, আমাদের ক্রিয়াকলাপে অ্যান্ড্রয়েড.উইজেট.সন্ধান ভিউয়ের মিশ্রণ ছিল তবে আমাদের মেনু_মাইন.এক্সএমএল ফাইলে v7 এর আংশিক ব্যবহার ছিল। .XML ফাইলটি অ্যাপটিও ব্যবহার করছে তা নিশ্চিত করুন: এক্সনভিউক্লাস = "android.support.v7.widget.S SearchView "ও।
gmcc051

0

সমর্থন লাইব্রেরি ভি 7 থেকে অনুসন্ধান ভিউটি কীভাবে পরিচালনা করবেন তার একটি স্নিপেট এখানে রয়েছে:

@Override
public void onCreateOptionsMenu(final Menu menu,final MenuInflater inflater)
  {
  menu.clear();
  getActivity().getMenuInflater().inflate(...,menu);
  _searchView=(SearchView)MenuItemCompat.getActionView(_searchMenuItem);
  _searchView.setQueryHint(...);

  if(VERSION.SDK_INT<VERSION_CODES.HONEYCOMB)
    {
    final EditText searchTextView=(EditText)searchView.findViewById(R.id.search_src_text);
    if(searchTextView!=null)
      {
      searchTextView.setScroller(new Scroller(_context));
      searchTextView.setMaxLines(1);
      searchTextView.setVerticalScrollBarEnabled(true);
      searchTextView.setMovementMethod(new ScrollingMovementMethod());
      searchTextView.setTextColor(_context.getResources().getColor(App.getResIdFromAttribute(_context,android.R.attr.textColorPrimary)));
      }
    }
  _searchView.setOnQueryTextListener(new android.support.v7.widget.SearchView.OnQueryTextListener()
    {
    ...
    });
  MenuItemCompat.setActionView(_searchMenuItem,_searchView);
  MenuItemCompat.setOnActionExpandListener(_searchMenuItem,new OnActionExpandListener()
    {
    ...
    });
  super.onCreateOptionsMenu(menu,inflater);
  }


public static int getResIdFromAttribute(final Activity activity,final int attr)
  {
  if(attr==0)
    return 0;
  final TypedValue typedvalueattr=new TypedValue();
  activity.getTheme().resolveAttribute(attr,typedvalueattr,true);
  return typedvalueattr.resourceId;
  }

এছাড়াও, আপনি যদি প্রোগার্ড ব্যবহার করেন তবে এটির কনফিগারেশনে এটি যুক্ত করুন:

-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class android.support.v7.widget.SearchView { *; }
-keepattributes *Annotation*

যারাই কোডটি ফর্ম্যাট করতে চেয়েছিল তাদের কাছে এটি "হোয়াইটস্মিথ" নামে পরিচিত একটি অতি পরিচিত ting অন্য স্বরূপে পরিবর্তন করা এটি আরও ভাল করে না, কারণ এটি স্বাদের বিষয়।
অ্যান্ড্রয়েড বিকাশকারী

@ জেজেডি হ্যাঁ সঠিক। এটি অন্যদের মতো সাধারণ নয়, তবে আমি এটি দীর্ঘকাল ব্যবহার করেছি। আপনি যদি চান তবে এটি Eclipse এ সেট করতে পারেন।
অ্যান্ড্রয়েড বিকাশকারী

ভাগ করে নেওয়ার জন্য ধন্যবাদ. আমি ডিফল্টর সাথে থাকি কারণ এটি দলের সদস্য বা অবদানকারীদের সাথে অনেক অযাচিত আলোচনা এড়িয়ে চলে।
জেজেডি

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

0

পার্থক্যটি হ'ল আমার সাথে একটি খুব একই বিষয় ছিল যা আমি বর্ধিত শ্রেণিটি ব্যবহার করার চেষ্টা করছিলাম android.widget.ImageView

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

-keep public class * extends android.widget.ImageView{
  public <init>(android.content.Context);
  public <init>(android.content.Context, android.util.AttributeSet);
  public <init>(android.content.Context, android.util.AttributeSet, int);
  public void set*(...);
}

http://proguard.sourceforge.net/manual/examples.html

এটি বলে, "এক্সএমএল থেকে কল হতে পারে এমন সমস্ত প্রয়োজনীয় নির্মাতাকে মঞ্জুর করুন এবং এটি যে কোনও কাস্টম সেটার ব্যবহার করার অনুমতি দিন (প্রয়োজনীয় হিসাবে আরও যোগ করুন)"


0

আমি জাভা কোডে ম্যানুয়াল সেট করে এটি করেছি:

<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/user_info"
        android:title="@string/user_name_title"
        app:actionLayout="@layout/menu_item_username"
        android:showAsAction="always" />
</menu>

লেআউট ফাইল:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/usr_name_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp"
        android:contentDescription="@string/user_info_image_des"
        android:padding="5dp"
        android:paddingStart="10dp"
        android:paddingEnd="10dp"
        android:text="@string/user_name_title"
        android:textStyle="bold"
        android:visibility="visible" />
</LinearLayout>

তারপরে জাভা কোডে:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.connect_menu, menu);
        // show user name on the top of menu
        Log.e("menu", "Size: " + menu.size());
        MenuItem item = menu.getItem(0);
        item.setActionView(R.layout.menu_item_username);
        View v = item.getActionView();
        if (null == v) {
            Log.e("NULL POINTER EX", "NULL MENU VIEW");
        } else {
            TextView usrNameTitle = v.findViewById(R.id.usr_name_title);
            if (null != usrName && usrName.length() > 0) {
                usrNameTitle.setText(usrName);
            }
        }
        return true;
    }

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


-1

কোড সরান: পাবলিক ক্লাস DemoActivity প্রসারিত ActionBarActivity

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


2
কেন সে এমন করবে? আপনার উত্তরটি আরও বিশদভাবে ব্যাখ্যা করুন।
রবিন এলার্কম্যান

আমি যখন অ্যাকশনবার্টিভিটি প্রসারিত করি তখন তা সর্বদা বাতিল হয়ে যায়। তবে আমি কেবল ক্রিয়াকলাপ প্রসারিত করি, এটি স্বাভাবিকভাবে কাজ করে
হিউউ

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