How to Disable touch on Action bar - android-actionbar

I want to disable touch event on action bar. Suggest me how to do it.
Note:I dont want to remove the action bar, I needs to be there, but should not be touchable.
I have tried this in my activity:
ActionBar ab = ((myActivity != null)? myActivity.getActionBar() : null);
if(ab ! = null) {
View v= ab.getCustomView();
}
if (v != null) {
v.setClickable(false);
v.setFocusable(false);
}
but it did not work.
Please sugges something.
Thanks In Advance..

I managed to fix this by making an invisible view over the entire activity.
and then punched a hole through some portion where if touched i coud dispatch the event to the main activity which is actually behind the invisible view activity,
getOwnerActivity().dispatchTouchEvent(event);

Related

MDI Tab names changing back... / Taskbar Preview not selecting

I'm creating an MDI application, WITHOUT the Document/View.
I am also using MDITabbedGroups.
I had a problem, because I have to name may tabs dynamically (names are in the DB and user created), meaning I couldn't use resources for the names.
I create all the tabs as 'Program name', then rename them by calling the following after create:
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_COMMAND(ID_SET_COLOR, CCOnSetColor)
END_MESSAGE_MAP()
PostMessage(WM_COMMAND, (WPARAM)ID_SET_COLOR);
void CChildView::CCOnSetColor()
{
CMDIChildWndEx* pFrame = (CMDIChildWndEx*)GetParent();
CMFCTabCtrl* pTabCtrl = pFrame->GetRelatedTabGroup();
if (pTabCtrl != NULL)
{
pTabCtrl->SetTabBkColor(pTabCtrl->GetActiveTab(), GetTabCol());
pTabCtrl->SetTabLabel(pTabCtrl->GetActiveTab(), GetTabName());
pTabCtrl->RedrawWindow();
}
}
But the problem was that when I switched tabs the names would change back to 'Program Name'.
I managed to avoid this by skipping over CMDIChildWndEx in the OnMDIActivate call as so:
void CChildFrame::OnMDIActivate(BOOL bActivate, CWnd* activated, CWnd* disbled)
{
CWnd::OnMDIActivate(bActivate, activated, disbled);
}
I know, I know, bad. However:
This worked fine, all other functionality seemed to be working, tabs were switching, active window was correct etc etc...
Until I noticed that on mouse over of the task bar, I got a preview of all open tabs, and if I clicked on one of the inactive tabs things went wrong.
Now the active frame / view (GetActiveFrame() / GetActiveView() in MainFrame) was the one I click on, but it is not drawn and the tab not switched to.
So I tried:
void CChildFrame::OnMDIActivate(BOOL bActivate, CWnd* activated, CWnd* disbled)
{
CMDIChildWndEx::OnMDIActivate(bActivate, activated, disbled);
CMFCTabCtrl* pTabCtrl = GetRelatedTabGroup();
if (pTabCtrl != NULL)
{
pTabCtrl->SetTabBkColor(pTabCtrl->GetActiveTab(), m_wndView.GetTabCol());
pTabCtrl->SetTabLabel(pTabCtrl->GetActiveTab(), m_wndView.GetTabName());
// pTabCtrl->SetTabIcon(pTabCtrl->GetActiveTab(), 2);
pTabCtrl->RedrawWindow();
}
}
&&&
void CChildFrame::OnMDIActivate(BOOL bActivate, CWnd* activated, CWnd* disbled)
{
CMDIChildWndEx::OnMDIActivate(bActivate, activated, disbled);
m_wndView.PostMessage(WM_COMMAND, (WPARAM)ID_SET_COLOR);
if(disbled) ((CChildFrame*)disbled)->m_wndView.PostMessage(WM_COMMAND, (WPARAM)ID_SET_COLOR);
}
Now the tab switches correctly, but only the tab being activated gets the correct name, all inactive tabs go back to 'Program Name'
interestingly the color remains correct.
So the Question:
Can I permanently change the name some how / where.
I saw in MS Documentation that it can be set in CDocument, but I don't have a Document...
Alternatively what call / calls do I need to catch to set my name every time?
Also Bonus Q:
Can I make the Preview show only the 'Active' Tab, and not the others?
After much hunting around in the AFX source files, I found this:
CString CMDIChildWndEx::GetFrameText() const
{
ASSERT_VALID(this);
CString strText;
GetWindowText(strText);
return strText;
}
& this
void CMDIFrameWnd::OnUpdateFrameTitle(BOOL bAddToTitle)
{
if ((GetStyle() & FWS_ADDTOTITLE) == 0)
return; // leave it alone!
... // rest of func
}
so it is as simple as removing the style flag the MS puts in automatically (via wizard create project), on the func BOOL PreCreateWindow(CREATESTRUCT& cs).
Then setting the title of the Frame via SetWindowText(title);

How can I change the animation between tab switches with a bottomNavigationView?

I have just updated my code to use the latest 2.4.0-alpha05 for the navigation component and I have custom navigation between the multiple stacks and my main nav graph is like the documentation I found.
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:startDestination="#+id/accounts"
android:id="#+id/bottom_nav">
<inclue app:graph="#navigation/accounts_tab_nav"/>
<include app:graph="#navigation/contact_tab_nav" />
<include app:graph="#navigation/profile_tab_nav" />
</navigation>
Most of my stacks animate with a slide from right to left. It looks like that when I am on the second screen, in let's say the profile screen, and then switch to the first tab it triggers the popEnter en popExitAnim that are defined in the action that leads to the second screen in the profile tab. Like so:
<fragment
android:id="#+id/profileMain"
android:name="com.app.ProfileFragment"
tools:layout="#layout/fragment_profile">
<action
android:id="#+id/action_profileMain_to_secondFragment"
app:destination="#id/secondFragment"
app:enterAnim="#anim/slide_in_right"
app:exitAnim="#anim/slide_out_left"
app:popEnterAnim="#anim/slide_in_left"
app:popExitAnim="#anim/slide_out_right" />
</fragment>
But obviously I want tho use the (default) fade animation when switching tabs. So how should I do that?
And I would like to pop to the root of the stack when reselecting a tab. But I probably have to do that myself?
I came up with a solution that seems to work for me, but I have to admit it feels a little bit hacky.
I have a public flag in my MainActivity:
var tabWasSelected = false
Then I remember if a tab item was selected in setOnItemSelectedListener
// always show selected Bottom Navigation item as selected (return true)
bottomNavigationView.setOnItemSelectedListener { item ->
// In order to get the expected behavior, you have to call default Navigation method manually
NavigationUI.onNavDestinationSelected(item, navController)
// set flag so that the fragment can call the correct animation on tab change in onCreateAnimation
tabWasSelected = true
return#setOnItemSelectedListener true
}
This will always select the item and navigate to the associated destination while maintaining multiple back stacks.
I then have created a Fragment class which all my other fragments inherit from. It simply overrides onCreateAnimation to set the correct animation. Here is what it looks like:
open class MyFragment: Fragment() {
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
val activity = requireActivity()
if (activity is MainActivity) {
if (activity.tabWasSelected) {
if (enter) {
//flow is exit first, then enter, so we have to reset the flag on enter
//in order that following animations will run as defined in the nav graph
activity.tabWasSelected = false
return AnimationUtils.loadAnimation(requireContext(), R.anim.nav_default_pop_enter_anim)
} else {
return AnimationUtils.loadAnimation(requireContext(), R.anim.nav_default_pop_exit_anim)
}
}
}
//no tab was selected, so run the defined animation
return super.onCreateAnimation(transit, enter, nextAnim)
}
}
Instead of using setupWithNavController function, follow this way.
First, create your NavOptions which include animation shown below.
val options = NavOptions.Builder()
.setLaunchSingleTop(true)
.setEnterAnim(R.anim.enter_from_bottom)
.setExitAnim(R.anim.exit_to_top)
.setPopEnterAnim(R.anim.enter_from_top)
.setPopExitAnim(R.anim.exit_to_bottom)
.setPopUpTo(navController.graph.startDestination,false)
.build();
Then use setOnNavigationItemSelectedListener to navigate with animation like that.
bottomNavigationView.setOnNavigationItemSelectedListener
{ item ->
when(item.itemId) {
R.id.fragmentFirst -> {
navController.navigate(R.id.fragmentFirst,null,options)
}
R.id.fragmentSecond -> {
navigate(R.id.fragmentSecond,null,options)
}
R.id.fragmentThird -> {
navController.navigate(R.id.fragmentThird,null,options)
}
}
}
Finally, you should prevent same item selection case so you can add below code.
bottomNavigationView.setOnNavigationItemReselectedListener
{ item ->
return#setOnNavigationItemReselectedListener
}
I used bottomNavigation like that in my project to add animation for page transitions. I hope it helped.

data-dialog created dynamically

I'm using polymer 1.0.
I'm trying to open a with on a clic on an element created dynamically with template repeat.
Here is the code :
<paper-button
data-dialog="modal"
on-click="dialogClick">
Click
</paper-button>
and the script (from doc) :
dialogClick: function(e) {
var button = e.target;
while (!button.hasAttribute('data-dialog') && button !== document.body) {
button = button.parentElement;
}
if (!button.hasAttribute('data-dialog')) {
return;
}
var id = button.getAttribute('data-dialog');
var dialog = document.getElementById(id);
alert(dialog);
if (dialog) {
dialog.open();
}
}
This work only if the value of data-dialog is simple text. If I want to change it by data-dialog="{{item.dialogName}}" for instance, it doesn't work. It is not found by the while loop and exit with the if. in the source code of the page, there is no data-dialog in the paper-button.
Any idea ?
I've ran into a similar problem when using data attributes on custom elements. You might want to subscribe to this polymer issue.
As a workaround, place the data attribute in a standard element that is a parent of the button and search for that one instead.
Also, you might want to consider using var button = Polymer.dom(e).localTarget instead of directly accessing e.target, since the later will give you an element deeper in the dom tree under shady dom.

How to hide propertysheet?

I had a propertysheet where I am facing an issue in hiding the sheet.I will briefly explain what I had done.
In the PropertySheet OnWizardFinish() I am trying hide the sheet and do the following ,
BOOL CSecondEditpage::OnWizardFinish()
{
BOOL bAsyRet = ShowWindowAsync(m_hWnd,SW_HIDE);
int MsgRet = ::MessageBox(NULL,L"Do you want to restart",L"Test",MB_YESNO | MB_ICONINFORMATION);
if(IDYES == MsgRet)
{
SystemRestart();
}
else
{
//Do Nothing..
}
return CPropertyPage::OnWizardFinish();
}
So here only the message box should be visible and the sheet should be hidden this is what I am expecting that ShowWindowAsync does.But in the background sheet still exists.
Same thing I tried with a dialog based application there it is working as expected like as,the background window is hidden and only message box is shown .
For more details:
And now when I click finish the sheet should be hidden and should show a message box something like this,
Can anyone please let me know how can achieve this in propertysheet wizard.
You're trying to hide PropertyPage not a PropertySheet.
Do like this.
CPropertySheet* prop = (CPropertySheet*)GetParent();
ShowWindowAsync(prop->m_hWnd, SW_HIDE);

How to abort saveui pipeline in Sitecore and then reset values?

I am trying to implement a saveui pipeline processor in Sitecore 6. Basically I have created a custom processor that presents the user with a popup message depending on which fields they may have changed on the item and what the new data is. If they made certain changes then they are presented with a popup asking them if they want to continue. If they answer no then the pipeline is aborted. That is all working. However I noticed that when you abort the pipeline all Sitecore seems to do is not save. All of the changes that the user made to the content item are still there in the UI. If you navigate away from the item in Sitecore, it will prompt you if you want to save the changes. Is there some way that I can get the Sitecore UI to cancel all of the changes and revert all of the fields back to their initial values? Aborting the pipeline is good because I don't want to save, but I also want to cancel the save in the UI too. Does anyone know how to do this?
Sample Code:
public class CustomSaveProcessor
{
public void Process(SaveArgs args)
{
Sitecore.Diagnostics.Assert.ArgumentNotNull(args, "args");
if(args.Items == null)
{ return; }
if(args.IsPostback)
{
if(args.Parameters["runContext"] == "firstQuestion")
{
if((args.Result == null) || (args.Result == "null") || (args.Result == "no") || (args.Result == "cancel"))
{
args.AbortPipeline();
//Should there be something here to tell the Sitecore UI to reset the values?
return;
}
else
{
//User has answered first question Yes
//This means they want to save the changes to the item
//We also want to ask a second question that effects other content items
SheerResponse.YesNoCancel("Do you want to also modify other items?", "300px", "200px");
args.Parameters["runContext"] = "secondQuestion";
args.WaitForPostBack();
}
}
else
{
if(args.Result == "yes")
{
//This is the answer to second question
//Custom code here to modify other content items
}
//We are completely done now.
return;
}
}
else
{
//Ask the user the first question
SheerResponse.YesNoCancel("Are you sure you want to proceed?", "300px", "200px");
args.Parameters["runContext"] = "firstQuestion";
args.WaitForPostback();
}
}
}
You can just reload the content tree with the following code.
String refresh = String.Format("item:refreshchildren(id={0})", Sitecore.Context.Item.Parent.ID);
Sitecore.Context.ClientPage.SendMessage(this, refresh);
Or as Corey discovered if you want to refersh the item you'd use
String refresh = String.Format("item:load(id={0})", myOriginalItem.ID);
Sitecore.Context.ClientPage.SendMessage(this, refresh);
See this post for more details
I think you can try to reload the current content item after aborting your custom save handler to set the intial values of the content item. Not sure if you then still get the "alert message".
Take a look at this post with a similiar issue