我一直在尝试将按钮的状态从开启切换到关闭,反之亦然,方法是添加图像打开并为关闭状态添加图像。我尝试了xml,但是我只能在点击时暂时切换它(使用按下/焦点等)。以下是相同的代码:
fragment_justin:
<RelativeLayout
android:id="@+id/top_bar_container"
android:layout_width="match_parent"
android:layout_height="48.5dp"
android:layout_alignParentTop="true"
android:background="@color/background_action_bar"
android:orientation="horizontal" >
<ImageButton
android:id="@+id/menu_button"
android:layout_width="30dp"
android:layout_height="48.5dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@android:color/transparent"
android:paddingRight="24dp"
android:src="@drawable/overflow_btn" />
<com.justin.abc.FontTextView
android:id="@+id/most_recent_text"
android:layout_width="wrap_content"
android:layout_height="48.5dp"
android:layout_marginLeft="11dp"
android:layout_marginRight="2dp"
android:textColor="@color/white"
foo:customFont="Cabin-Bold.ttf"
android:layout_alignParentLeft="true"
android:textSize="18sp"
android:gravity="center_vertical"
android:text="@string/most_recent"/>
</RelativeLayout>
只关注图像按钮部分,你会看到overflow_btn。现在overflow_btn是一个在drawable下调用的类,如下所示:
overflow_btn:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="false"
android:drawable="@drawable/overflow_pressed" />
<item
android:state_pressed="true"
android:state_enabled="true"
android:drawable="@drawable/overflow_pressed" />
<item
android:state_focused="true"
android:state_enabled="true"
android:drawable="@drawable/overflow_pressed" />
<item
android:state_enabled="true"
android:drawable="@drawable/overflow" />
</selector>
使用上面的代码后,它只在点击时暂时切换按钮状态(如闪烁到overflow_pressed)并恢复为溢出。 我相信java代码中可能需要进行一些更改才能实现,因此这里是相应的java类:
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_justin, container, false);
createMenus() ;
setOnclickListeners(view);
mAdapter = new CursorAdapter(getActivity(), null, 0);
final ListView list = (ListView) view.findViewById(R.id.justin_list);
list.setAdapter(mAdapter);
list.setOnItemLongClickListener(this);
list.setOnTouchListener(this);
list.setOnItemClickListener(this);
LayoutUtils.showLoading(view, R.id.justin_list);
return view;
}
private void setOnclickListeners(final View view){
final ImageButton button = (ImageButton) view.findViewById(R.id.menu_button);
button.setOnClickListener(this);
}
private void createMenus() {
mPreferenceMenuItems.add(PreferenceMenuItems.JUSTIN_PREFERENCES);
mPreferencesMenuHelper = new MenuHelper(getActivity(), mPreferenceMenuItems,this);
mDeleteMenuItems.add(DeleteMenuItems.DELETE_JUSTIN);
mDeleteMenuHelper = new MenuHelper(getActivity(), mDeleteMenuItems,this);
}
@Override
public void onResume() {
super.onResume();
final MainActivity activity = (MainActivity) getActivity();
activity.updateActionBarTitle();
final IntentFilter filter = new IntentFilter();
activity.getApplicationContext().registerReceiver(mReceiver, filter);
}
@Override
public void onPause() {
getActivity().getApplicationContext().unregisterReceiver(mReceiver);
super.onPause();
}
@Override
public void onCursorLoaded(final Uri uri, final Cursor cursor) {
if (cursor.getCount() > 0) {
mAdapter.swapCursor(cursor);
showResults(uri);
} else {
if (!isOperationExecuting()) {
showNoResults(uri);
}
}
}
@Override
public void onMenuItemClicked(final int position) {
if (isPreferences) {
switch (position) {
case PreferenceMenuItems.JUSTIN_PREFERENCES_POSITION:
PreferencesActivity.newInstance(getActivity());
break;
default:
break;
}
mPreferencesMenuHelper.hideMenu();
} else {
switch (position) {
case DeleteMenuItems.DELETE_POSITION:
final DialogFragment dialog = new DeleteFromDialogFragment();
final Bundle bundle = new Bundle();
bundle.putString(JUSTIN_ID, mJustinID);
dialog.setArguments(bundle);
dialog.show(getFragmentManager(), DELETE_FROM_JUSTIN );
break;
default:
break;
}
mDeleteMenuHelper.hideMenu();
}
}
@Override
public void onClick(final View view) {
switch (view.getId()) {
case R.id.justin_menu_button:
final Activity activity = getActivity();
final int actionBarHeight = activity.findViewById(R.id.title_main_container).getHeight();
final int menuBarHeight = activity.findViewById(R.id.justin_top_bar_container).getHeight();
mPreferencesMenuHelper.showMenu(actionBarHeight + menuBarHeight, Gravity.RIGHT, R.style.MenuDialogAnimation);
isPreferences = true;
break;
default:
break;
}
}
@Override
public void showResults(final Uri uri) {
if (mIsAnimating) {
mShouldShowResult = true;
} else {
LayoutUtils.showResults(getView(), R.id.justin_list);
mShouldShowResult = false;
}
}
@Override
public void showNoResults(final Uri uri) {
if (mIsAnimating) {
mShouldShowNoResult = true;
} else {
LayoutUtils.showNoResult(getView(), R.id.justin_list, getResources().getString(R.string.no_result));
mShouldShowNoResult = false;
}
}
@Override
public void onOperationStarted(final Uri uri) {
LayoutUtils.showLoading(getView(), R.id.justin_list);
}
@Override
public boolean onItemLongClick(final AdapterView<?> adapter, final View view, final int position, final long id) {
isPreferences = false;
final Activity activity = getActivity();
final int actionBarHeight = activity.findViewById(R.id.title_main_container).getHeight();
final int menuBarHeight = activity.findViewById(R.id.justin_top_bar_container).getHeight();
mDeleteMenuHelper.showMenu(mYValue + actionBarHeight + menuBarHeight, Gravity.CENTER, R.style.MenuDialogAnimation);
final Cursor cursor = (Cursor) mAdapter.getItem(position);
mJustinID = cursor.getString(cursor.getColumnIndex(Justin.Columns.ID));
return false;
}
@Override
public boolean onTouch(final View v, final MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
mYValue = (int)event.getY();
}
return false;
}
public void restartLoader(){
getContentLoader().restartLoader();
}
@Override
public void onItemClick(final AdapterView<?> adapter, final View view, final int position, final long id) {
final Cursor cursor = (Cursor) mAdapter.getItem(position);
if (!NetworkUtils.isOnline() && ContentProvider.isStoryEmty(cursor)) {
final DialogFragment dialog = new CheckOfflineAccessDialogFragment();
dialog.show(getFragmentManager(), OFFLINE_ACCESS);
return;
}
final String documentSource = cursor.getString(cursor.getColumnIndex(Justin.Columns.SOURCE));
final ArticlePagerFragment ArticlePagerFragment = ArticlePagerFragment.newInstance(getFragmentManager(), position, documentSource, false);
ArticlePagerFragment.setFragment(this);
}
public static String getArticleID(final Cursor cursor) {
final String documentLink = cursor.getString(cursor.getColumnIndex(Justin.Columns.DOCUMENT_LINK));
final String documentType = cursor.getString(cursor.getColumnIndex(Justin.Columns.TYPE));
final String source = cursor.getString(cursor.getColumnIndex(Justin.Columns.SOURCE));
String articleID = "";
if (source.equalsIgnoreCase(Justin.NEWS_SOURCE_VALUE) && documentType.equalsIgnoreCase(Justin.TEXT_TYPE)) {
articleID = documentLink.substring(documentLink.lastIndexOf("storyId=")+8);
}
return articleID;
}
知道如何做同样的事情吗?
MenuHelper:
public class MenuHelper implements OnItemClickListener{
private final Dialog mMenu;
private final OnMenuItemClickedListener mMenuItemListener;
private final ArrayAdapter<String> mAdapter;
private final int MENU_ITEM_HEIGHT = 40; // Defined in res/layout/menu_item.xml
private List<Boolean> enabledStates;
public MenuHelper(final Context context, final List<String> menuItems, final OnMenuItemClickedListener menuItemListener) {
mMenu = new Dialog(context);
mMenu.requestWindowFeature(Window.FEATURE_NO_TITLE);
mMenu.setContentView(R.layout.menu_container);
enabledStates = new ArrayList<Boolean>(menuItems.size());
for(int i = 0; i < menuItems.size(); i++) {
enabledStates.add(true);
}
final ListView menuList = (ListView) mMenu.findViewById(R.id.menu_list);
mAdapter = new ArrayAdapter<String>(context, R.layout.menu_item, menuItems) {
@Override
public boolean isEnabled(int position) {
return enabledStates.get(position);
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
if(enabledStates.get(position)) {
((TextView) view).setTextColor(Application.getAppResources().getColor(R.color.white));
} else {
((TextView) view).setTextColor(Application.getAppResources().getColor(R.color.disabled_gray));
}
if (convertView == null) {
convertView = super.getView(position, convertView, parent);
}
// check for odd or even to set alternate colors to the row background
if (position % 2 == 0) {
convertView.setBackgroundResource(R.drawable.oddcellcolor);
} else {
convertView.setBackgroundResource(R.drawable.evencellcolor);
}
return convertView;
//return view;
}
};
menuList.setOnItemClickListener(this);
menuList.setAdapter(mAdapter);
mMenuItemListener = menuItemListener;
}
public void showMenu(final int yPosition, final int horizontalGravity) {
showMenu(yPosition, horizontalGravity, R.style.MenuDialogAnimation);
}
public void setEnabled(int position, boolean isEnabled) {
enabledStates.set(position, isEnabled);
mAdapter.notifyDataSetChanged();
}
public void setEnabledAll(boolean isEnabled) {
for(int ii = 0; ii < enabledStates.size(); ii++) {
enabledStates.set(ii, isEnabled);
}
mAdapter.notifyDataSetChanged();
}
public int getMenuHeight() {
if (mMenu != null) {
return (int) (mAdapter.getCount() * MENU_ITEM_HEIGHT / Application.getAppResources().getDisplayMetrics().density);
} else {
return -1;
}
}
public void showMenu(final float yPosition, final int horizontalGravity, final int animation) {
final Window window = mMenu.getWindow();
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
if (horizontalGravity != Gravity.CENTER) {
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
}
final WindowManager.LayoutParams params = window.getAttributes();
params.gravity = Gravity.TOP | horizontalGravity;
params.y = Math.round(yPosition);
params.windowAnimations = animation;
window.setAttributes(params);
mMenu.show();
}
public void hideMenu() {
mMenu.hide();
}
@Override
public void onItemClick(final AdapterView<?> adapter, final View view, final int position, final long parent) {
mMenuItemListener.onMenuItemClicked(position);
}
}
谢谢! 贾斯汀
答案 0 :(得分:2)
我同意@Chronos,听起来更像是一个有两个州的ToggleButton。保持简单,这是我可以用来作为一个例子。没有必要的代码,只需xml。
这是我布局的xml:
<ToggleButton
android:id="@+id/btnHeadache"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerHorizontal="true"
android:background="@drawable/headache_button"
android:paddingTop="25sp"
android:text="@string/headache"
android:textOn=""
android:textOff="" />
现在这里是不同状态的xml,当然在我的drawable文件夹中包含图像。如果上面不清楚,则将其命名为headache_button.xml。:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/check" android:state_checked="true"/> <!-- currently pressed turning the toggle on -->
<item android:drawable="@drawable/headache" android:state_checked="false" /> <!-- currently pressed turning the toggle off -->
</selector>
答案 1 :(得分:1)
您可以使用以下代码在代码中执行此操作:
// Declare button
// Set its original background image
button.setBackground(getResources().getDrawable(R.drawable.original_button_image));
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Choose whichever image for pressed state
v.setBackground(getResources().getDrawable(R.drawable.button_is_pressed));
new Handler().postDelayed(new Runnable() {
public void run() {
v.setBackground(getResources().getDrawable(R.drawable.original_button_image));
// Button Click Code Here
}
}, 100L); // Change this value to whatever is suitable
}
});
修改1 :
<ImageButton
android:id="@+id/menu_button"
android:layout_width="30dp"
android:layout_height="48.5dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@android:color/transparent"
android:src="@drawable/testdrawable"
android:paddingRight="24dp" />
由于该按钮只有两种状态,请尝试testdrawable
而不是您在问题中发布的状态:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="true"
android:drawable="@drawable/overflow_pressed" />
<item
android:drawable="@drawable/overflow" />
</selector>
将您的onClick(View)
更改为:
@Override
public void onClick(final View view) {
switch (view.getId()) {
case R.id.justin_menu_button:
if (button.isSelected()) {
button.setSelected(false);
isPreferences = false;
mPreferencesMenuHelper.hideMenu();
Log.i("ImageButtonCheck", "Button is not selected anymore");
} else {
button.setSelected(true);
final Activity activity = getActivity();
final int actionBarHeight = activity.findViewById(R.id.title_main_container).getHeight();
final int menuBarHeight = activity.findViewById(R.id.justin_top_bar_container).getHeight();
mPreferencesMenuHelper.showMenu(actionBarHeight + menuBarHeight, Gravity.RIGHT, R.style.MenuDialogAnimation);
isPreferences = true;
Log.i("ImageButtonCheck", "Button is in selected state");
}
break;
default:
break;
}
}
将onMenuItemClicked(int)
更改为:
@Override
public void onMenuItemClicked(final int position) {
if (isPreferences) {
switch (position) {
case PreferenceMenuItems.JUSTIN_PREFERENCES_POSITION:
PreferencesActivity.newInstance(getActivity());
break;
default:
break;
}
isPreferences = false;
button.setSelected(false);
mPreferencesMenuHelper.hideMenu();
Log.i("ImageButtonCheck", "Button is not in a selected state because of a menu item click");
} else {
switch (position) {
case DeleteMenuItems.DELETE_POSITION:
final DialogFragment dialog = new DeleteFromDialogFragment();
final Bundle bundle = new Bundle();
bundle.putString(JUSTIN_ID, mJustinID);
dialog.setArguments(bundle);
dialog.show(getFragmentManager(), DELETE_FROM_JUSTIN );
break;
default:
break;
}
mDeleteMenuHelper.hideMenu();
}
}
我认为这里的问题是,当第一次按下按钮时,将实现所选状态并显示菜单。但是,在显示菜单时再次单击该按钮不会调用onClick(View)
方法。我在上面的代码中包含了3个日志语句。让我知道您在logcat中看到的输出,当您单击按钮一次以显示菜单并再次单击菜单以隐藏它时。这两次点击的输出应为"Button is in selected state"
和"Button is not selected anymore"
。
编辑2 :
将MenuHelper
包含在您的活动类中作为内部类:
public class MenuHelper implements OnItemClickListener, Dialog.OnDismissListener {
private final Dialog mMenu;
private final OnMenuItemClickedListener mMenuItemListener;
private final ArrayAdapter<String> mAdapter;
private final int MENU_ITEM_HEIGHT = 40; // Defined in res/layout/menu_item.xml
private List<Boolean> enabledStates;
public MenuHelper(final Context context, final List<String> menuItems, final OnMenuItemClickedListener menuItemListener) {
mMenu = new Dialog(context);
mMenu.requestWindowFeature(Window.FEATURE_NO_TITLE);
mMenu.setContentView(R.layout.menu_container);
mMenu.setOnDismissListener(this); -------------------------> **add this**
enabledStates = new ArrayList<Boolean>(menuItems.size());
for(int i = 0; i < menuItems.size(); i++) {
enabledStates.add(true);
}
final ListView menuList = (ListView) mMenu.findViewById(R.id.menu_list);
mAdapter = new ArrayAdapter<String>(context, R.layout.menu_item, menuItems) {
@Override
public boolean isEnabled(int position) {
return enabledStates.get(position);
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
if(enabledStates.get(position)) {
((TextView) view).setTextColor(Application.getAppResources().getColor(R.color.white));
} else {
((TextView) view).setTextColor(Application.getAppResources().getColor(R.color.disabled_gray));
}
if (convertView == null) {
convertView = super.getView(position, convertView, parent);
}
// check for odd or even to set alternate colors to the row background
if (position % 2 == 0) {
convertView.setBackgroundResource(R.drawable.oddcellcolor);
} else {
convertView.setBackgroundResource(R.drawable.evencellcolor);
}
return convertView;
//return view;
}
};
menuList.setOnItemClickListener(this);
menuList.setAdapter(mAdapter);
mMenuItemListener = menuItemListener;
}
public void showMenu(final int yPosition, final int horizontalGravity) {
showMenu(yPosition, horizontalGravity, R.style.MenuDialogAnimation);
}
public void setEnabled(int position, boolean isEnabled) {
enabledStates.set(position, isEnabled);
mAdapter.notifyDataSetChanged();
}
public void setEnabledAll(boolean isEnabled) {
for(int ii = 0; ii < enabledStates.size(); ii++) {
enabledStates.set(ii, isEnabled);
}
mAdapter.notifyDataSetChanged();
}
public int getMenuHeight() {
if (mMenu != null) {
return (int) (mAdapter.getCount() * MENU_ITEM_HEIGHT / Application.getAppResources().getDisplayMetrics().density);
} else {
return -1;
}
}
public void showMenu(final float yPosition, final int horizontalGravity, final int animation) {
final Window window = mMenu.getWindow();
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
if (horizontalGravity != Gravity.CENTER) {
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
}
final WindowManager.LayoutParams params = window.getAttributes();
params.gravity = Gravity.TOP | horizontalGravity;
params.y = Math.round(yPosition);
params.windowAnimations = animation;
window.setAttributes(params);
mMenu.show();
}
public void hideMenu() {
mMenu.hide();
}
@Override
public void onItemClick(final AdapterView<?> adapter, final View view, final int position, final long parent) {
mMenuItemListener.onMenuItemClicked(position);
}
@Override
public void onDismiss(DialogInterface arg0) {
button.setSelected(false);
}
}
答案 2 :(得分:1)
如果我理解得很好,你需要一个ToggleButton,一个有两种状态的按钮。
使用像这样的选择器:
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/btn_normal" android:state_checked="false"/>
<item android:drawable="@drawable/btn_pressed" android:state_checked="true"/>
</selector>
答案 3 :(得分:0)
这听起来更像是你应该使用CheckBox。常规按钮没有“开启”状态,只需按下并聚焦。使用复选框,您需要使用android:state_checked="true"
。单击该复选框将切换到选中状态,再次单击它会将其切换回默认状态(未选中)。
在确定不能使用XML之前,请尽量不要添加额外的java代码。
答案 4 :(得分:0)
如果我理解你的话,你需要一个有两种状态的'按钮',然后用它在它们之间切换。
在这种情况下,它看起来更像是你想要'ToggleButton','CompoundButton'或'Switch'的行为。你可以使用'android在xml中配置它们 :state_checked'根据@Chronos。