it-swarm.com.ru

Установить OnClick Listener на заголовке панели действий в Android

Я работаю над приложением Android, в котором я использую ActionBar, поэтому там есть значок на панели навигации, чтобы открыть его, и название ActionBar в ActionBar. Я хочу установить прослушиватель щелчков на заголовке ActionBar так, чтобы он запускал новый Activity, и настроить прослушиватель щелчков на значке навигационной панели, чтобы открыть меню навигационной панели.

Я нажал на иконку навигационной панели, но когда я щелкаю на заголовке ActionBar title, то он открывает меню навигационной панели. Есть ли способ установить другой прослушиватель кликов по названию ActionBar.

Заранее спасибо.

22
N Sharma

Попробуйте добавить этот код в функцию onCreate (). Это захватит ресурс, под которым находится заголовок панели действий, и назначит ему идентификатор, который вы можете использовать для добавления OnClickListener. Дайте мне знать, как это происходит!

final int abTitleId = getResources().getIdentifier("action_bar_title", "id", "Android");
findViewById(abTitleId).setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
    //Do something
    }
});
22
Jake Weso

Вы можете использовать собственный макет для заголовка и назначить для него слушателя:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ActionBar actionBar = getActionBar();
    if (actionBar != null) {
        // Disable the default and enable the custom
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setDisplayShowCustomEnabled(true);
        View customView = getLayoutInflater().inflate(R.layout.actionbar_title, null);
        // Get the textview of the title
        TextView customTitle = (TextView) customView.findViewById(R.id.actionbarTitle);


        // Change the font family (optional)
        customTitle.setTypeface(Typeface.MONOSPACE);
        // Set the on click listener for the title
        customTitle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.w("MainActivity", "ActionBar's title clicked.");
            }
        });
        // Apply the custom view
        actionBar.setCustomView(customView);
    }
}

actionbar_title.xml :

<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="vertical"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:gravity="center">

    <TextView
        Android:id="@+id/actionbarTitle"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:textSize="25sp"
        Android:text="@string/app_name"/>

</LinearLayout>
15
Simas

Я думаю ответ Симаса самый лучший, но вот хакерская версия, если вы предпочитаете это.

ViewTools.findActionBarTitle(getWindow().getDecorView()).setOnClickListener(...);

Этот должен быть универсальным в том смысле, что он работает с:

  • стоковый Android ActionBar
  • Theme.AppCompat поддержка ActionBar
  • v21-style setActionBar
    использовать <Toolbar Android:id="@+id/action_bar"
    или передайте завышенную Toolbar как root
  • v21-style setSupportActionBar
    использовать <Android.support.v7.widget.Toolbar Android:id="@id/action_bar"
    или передайте завышенную Toolbar как root
  • пользовательские реализации Toolbar могут потребовать небольшой корректировки,
    но тогда вы можете заключить это в этот пользовательский класс.

Хотя я тестировал только с поддержкой: v22.

/** @param root usually Activity.getWindow().getDecorView() or your custom Toolbar */
public static @Nullable View findActionBarTitle(@NonNull View root) {
    return findActionBarItem(root, "action_bar_title", "mTitleTextView");
}
/** @param root usually Activity.getWindow().getDecorView() or your custom Toolbar */
public static @Nullable View findActionBarSubTitle(@NonNull View root) {
    return findActionBarItem(root, "action_bar_subtitle", "mSubtitleTextView");
}

private static @Nullable View findActionBarItem(@NonNull View root,
        @NonNull String resourceName, @NonNull String toolbarFieldName) {
    View result = findViewSupportOrAndroid(root, resourceName);

    if (result == null) {
        View actionBar = findViewSupportOrAndroid(root, "action_bar");
        if (actionBar != null) {
            result = reflectiveRead(actionBar, toolbarFieldName);
        }
    }
    if (result == null && root.getClass().getName().endsWith("widget.Toolbar")) {
        result = reflectiveRead(root, toolbarFieldName);
    }
    return result;
}

@SuppressWarnings("ConstantConditions")
private static @Nullable View findViewSupportOrAndroid(@NonNull View root, @NonNull String resourceName) {
    Context context = root.getContext();
    View result = null;
    if (result == null) {
        int supportID = context.getResources().getIdentifier(resourceName, "id", context.getPackageName());
        result = root.findViewById(supportID);
    }
    if (result == null) {
        int androidID = context.getResources().getIdentifier(resourceName, "id", "Android");
        result = root.findViewById(androidID);
    }
    return result;
}

@SuppressWarnings("unchecked")
public static <T> @Nullable T reflectiveRead(@NonNull Object object, @NonNull String fieldName) {
    try {
        Field field = object.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        return (T)field.get(object);
    } catch (Exception ex) {
        Log.w("HACK", "Cannot read " + fieldName + " in " + object, ex);
    }
    return null;
}
9
TWiStErRob

Если вы используете Панель инструментов с поддержкой v7: 21 . Проверьте следующий код:

Field titleField = Toolbar.class.getDeclaredField("mTitleTextView");
        titleField.setAccessible(true);
        TextView barTitleView = (TextView) titleField.get(mToolbar);
        barTitleView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

            }
        });
7
Dejavu

Вы можете сделать это легко с помощью панели инструментов. Определите панель инструментов в файле макета XML, как показано ниже:

 <Android.support.v7.widget.Toolbar
    Android:id="@+id/toolbar"
    Android:layout_width="match_parent"
    Android:layout_height="?actionBarSize"
    Android:background="?colorPrimary"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <TextView
        Android:id="@+id/toolbarTitle"
        style="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"
        Android:background="?attr/selectableItemBackground"
        Android:layout_width="wrap_content"
        Android:gravity="center_vertical"
        Android:layout_height="match_parent" />
</Android.support.v7.widget.Toolbar>

Затем вы можете установить слушателя в Activity, используя этот код:

setSupportActionBar((Toolbar) findViewById(R.id.toolbar));

TextView toolbarTitle= (TextView) findViewById(R.id.toolbarTitle);
toolbarTitle.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // DO SOMETHING HERE
        }
    });
6
jimmy0251

Если вы хотите использовать существующую в данный момент панель действий, а не панель инструментов, используйте следующее:

ActionBar actBar = getSupportActionBar();
if(actBar != null) {
    actBar.setTitle(R.string.your_ab_title);
 }

//Set actions to take when the AB is clicked
Toolbar ab = findViewById(R.id.action_bar);
if(ab != null){
    for (int i= 0; i < ab.getChildCount(); i++){

        View child = ab.getChildAt(i);

        if(child instanceof TextView || child instanceof ImageView) {
            child.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String url = "http://www.HoverDroids.com";

                    Intent i = new Intent(Intent.ACTION_VIEW);
                    i.setData(Uri.parse(url));
                    startActivity(i);
                }
            });
        }
     }
}    
1
Chris Sprague

Вы можете сделать это легко с помощью панели инструментов. Определите панель инструментов в файле макета XML, как показано ниже:

    <Android.support.v7.widget.Toolbar
    Android:id="@+id/MainActivityToolbar"
    Android:layout_width="match_parent"
    Android:layout_height="?attr/actionBarSize"
    Android:background="@color/colorPrimary"
    app:layout_scrollFlags="scroll|enterAlways"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" >
    <RelativeLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" >
        <TextView
            Android:layout_width="wrap_content"
            Android:layout_height="match_parent"
            Android:text="@string/app_name"
            Android:textSize="30sp"
            tools:ignore="RelativeOverlap"

            Android:layout_marginTop="10dp"
            Android:layout_marginBottom="10dp"
            Android:layout_marginRight="10dp"
            Android:layout_marginLeft="10dp"
            />
        <Button
            Android:id="@+id/LogOutButton"
            Android:layout_width="100dp"
            Android:layout_height="wrap_content"
            Android:layout_alignParentEnd="true"
            Android:layout_alignParentRight="true"

            Android:layout_marginTop="10dp"
            Android:layout_marginBottom="10dp"
            Android:layout_marginRight="10dp"
            Android:layout_marginLeft="10dp"

            Android:text="@string/logout" />
    </RelativeLayout>

</Android.support.v7.widget.Toolbar>

Затем вы можете установить слушателя в Activity, используя этот код:

setSupportActionBar((Toolbar) findViewById(R.id.MainActivityToolbar));

logOutButton =  findViewById(R.id.LogOutButton);
logOutButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
   //define your function for logout or something else 
   LogOut();
 }
});
0
Wajid khan

Если вам известен фактический текст в вашем заголовке, и вы достаточно уверены, что никакой другой TextView на экране не разделяет этот заголовок, вы можете использовать рекурсивный поиск по дереву просмотра, чтобы найти его. 

Это отличное решение, потому что оно не требует отражения внутренних знаний о том, как строится панель инструментов, и дает вам прямой доступ к TextView.

@Nullable
public static TextView findTextViewWithText(@Nullable View toCheck, String toFind) {

    if (toCheck instanceof TextView) {
        String foundText = ((TextView) toCheck).getText().toString();
        if (foundText.equals(toFind)) {
            return (TextView) toCheck;
        }

    } else if (toCheck instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) toCheck).getChildCount(); i++) {
            TextView found = findTextViewWithText(((ViewGroup) toCheck).getChildAt(i), toFind);
            if (found != null) {
                return found;
            }
        }
    }
    return null;
}

Самый надежный вид для вызова - это декор, но не стесняйтесь экспериментировать, что лучше всего подходит для ваших целей, ваш пробег может варьироваться.

View found = findTextViewWithText(
    getActivity().getWindow().getDecorView(), "My Title");
if (found != null) {
  // Do something, like set a click listener
}
0
Kevin Grant