Android Custom Keyboard Implementation - android-keypad

I am developing Android custom keyboard. I imported android.view.inputmethod.InputMethodSubtype in my code while doing this I am getting an error message like this imported one cannot be resolved. Is there any eclipse plugin I need to install, as per my knowledge Android version above 1.6 will support IMF.

The question is very old but I am answering it as it might help another user who sees this.
OP asked if there is any plugin for Eclipse to install to resolve the issue but now we have Android Studio.
For those who want to implement Android Custom Keyboard:
First, download Google sample project for Android Custom Keyboard to start with.
There are three important features to decide which one you want: 1) theme (custom layout), 2) subtype and 3) emoticons.
For themes/ layouts: Create layout files. See the example code below:
<com.domain.keyboard.android.LatinKeyboardView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/keyboard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#drawable/kb_bg_9"
android:keyBackground="#drawable/key_bg_fill_white"
android:keyPreviewLayout="#layout/key_preview_layout"
android:keyPreviewOffset="#dimen/keyPreviewOffset"
android:keyTextColor="#color/white"
android:popupLayout="#layout/keyboard_popup_layout" />
And use the following code in SoftKeyboard.java:
#Override
public View onCreateInputView() {
// Set custom theme to input view.
int themeLayout = sharedPreferences.getInt(THEME_KEY, R.layout.input_1);
mInputView = (LatinKeyboardView) getLayoutInflater().inflate(
themeLayout, null);
mInputView.setOnKeyboardActionListener(this);
// Close popup keyboard when screen is touched, if it's showing
mInputView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
mInputView.closing();
}
return false;
}
});
// Apply the selected keyboard to the input view.
setLatinKeyboard(getSelectedSubtype());
return mInputView;
}
For subtype: Create a copy of qwerty.xml and edit it to replace the keys. Create another instance of LatinKeyboard in SoftKeyboard.java and use if or switch logic.
private LatinKeyboard getSelectedSubtype() {
final InputMethodSubtype subtype = mInputMethodManager.getCurrentInputMethodSubtype();
String s = subtype.getLocale();
switch (s) {
case "ps_AF":
mActiveKeyboard = mPashtoKeyboard;
mCurKeyboard = mPashtoKeyboard;
break;
case "fa_AF":
mCurKeyboard = mFarsiKeyboard;
break;
default:
mCurKeyboard = mQwertyKeyboard;
}
return mCurKeyboard;
}
And edit methods.xml to add subtypes:
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="com.sunzala.afghankeyboard.android.ImePreferences"
android:supportsSwitchingToNextInputMethod="true">
<subtype
android:imeSubtypeLocale="en_US"
android:imeSubtypeMode="keyboard"
android:label="#string/label_subtype_generic" />
<subtype
android:imeSubtypeLocale="ps_AF"
android:imeSubtypeMode="keyboard"
android:label="#string/label_subtype_generic" />
<subtype
android:imeSubtypeLocale="fa_AF"
android:imeSubtypeMode="keyboard"
android:label="#string/label_subtype_generic" />
</input-method>
For emoticons: Find library and integrate it with a keyboard. The emoticons will display with a key press.
if (primaryCode == -10000) {
showEmoticons();
}
Where -10000 is keycode.

Related

Can You Minimize the Soft Keyboard on Android From Text Completed Event

I've seen various answers to this question for older versions but not sure how to translate to MAUI. The question being, is there a way that you can minimize the soft keyboard on a device from the Text Completed event of an Entry control?
I finally figured out how to do this. This solution is for Android only right now. It doesn't use a custom handler since I could not get the window token from PlatformView. Instead the code looks like this:
#if ANDROID
var imm = (Android.Views.InputMethods.InputMethodManager)MauiApplication.Current.GetSystemService(Android.Content.Context.InputMethodService);
if (imm != null)
{
//this stuff came from here: https://www.syncfusion.com/kb/12559/how-to-hide-the-keyboard-when-scrolling-in-xamarin-forms-listview-sflistview
var activity = Microsoft.Maui.ApplicationModel.Platform.CurrentActivity;
Android.OS.IBinder wToken = activity.CurrentFocus?.WindowToken;
imm.HideSoftInputFromWindow(wToken, 0);
}
#endif
So credit to the syncfusion folks that published their version, and this code above is modified from that to work in MAUI.
The code belongs in a custom handler. Based on Customize a control with a mapper.
In that Maui handler, handler.PlatformView is the Android control. Xamarin.Android properties/methods would be on that.
Something like:
using Microsoft.Maui.Platform;
namespace CustomizeHandlersDemo;
public partial class CustomizeEntryPage : ContentPage
{
public CustomizeEntryPage()
{
InitializeComponent();
ModifyEntry();
}
void ModifyEntry()
{
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping(
"MyCustomization", (handler, view) =>
{
#if ANDROID
handler.PlatformView....
#elif IOS
#elif WINDOWS
#endif
});
}
}
NOTE: That example modifies ALL Entries.
If you want to modify only SOME Entries, you instead define a subclass (e.g. public class MyEntry : Entry {}), and do this:
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping(
"MyEntryCustomizationOrWhatever", (handler, view) =>
{
if (view is MyEntry)
{
#if ANDROID
handler.PlatformView....
#elif IOS
#elif WINDOWS
#endif
}
});
For your specific situation, the line you were having trouble adapting to Maui contains btnSignIn.WindowToken.
Replace that with handler.PlatformView.WindowToken.

Open DialectEditor programmatically outside of main editor area (E3/E4 hybrid)

what I want to do:
In my RCP an E3/E4 hybrid I have a project and library based on sirius tree. The User can drag an drop item from the library tree to the project tree. This works fine and was no great problem to build in. So now I want to make the UI more usable. It should looks like this layout:
what works:
After application startup I open my library presentation with the DialectUIManager.
final DialectEditor editor = (DialectEditor)
DialectUIManager.INSTANCE.openEditor(siriusSession, description, monitor);
Okay, this works. But it open it in the editor in the part market as org.eclipse.ui.editorss. This it not what I want
what does not work:
I want to show it in the "Library Part". I can move it manually with the mouse after open the editor, but how can i tell DialectUIManager to open it direct there. Or how can I programmatically it move there.
I do a lot of google research but i don't found a solution. The only thing I found was a hint Pierre-Charles David https:// www. eclipse.org/forums/index.php?t=msg&th=998476&goto=1631138&#msg_1631138
If you need is simply to show the editor outside of the main editor
area, this is possible since Eclipse 4.2 (e4 does not really treat the
main editor area as something special), so you can have your editor
"around" another editor in the middle of other views.
But at this step I stuck. I also ask it in the Sirius Forum but they say its a Eclipse E4 problem
Thanks for help, code snippets or links to correct part of manual.
I've found a solution. It's not very nice, but it works. I execute these code here after the editors have opened.
What the code does:
He is looking for the MPlaceholder which has the ID: org. eclipse. ui. editorss. There he descends until he is with the parts. These are in the Compatibly editor mode. Then he chooses the part we wants to move out of and Attach them to the MPartStack target.
public static void movePart(MApplication application,
EModelService modelService) {
MPart partToMove = null;
MUIElement muiElement =
modelService.find("org.eclipse.ui.editorss", application);
if (muiElement instanceof MPlaceholder) {
MPlaceholder placeholder = (MPlaceholder) muiElement;
MUIElement ref = placeholder.getRef();
if (ref instanceof MArea) {
MArea area = (MArea) ref;
List<MPartSashContainerElement> children = area.getChildren();
for (MPartSashContainerElement mPartSashContainerElement
: children) {
if (mPartSashContainerElement instanceof MPartStack) {
MPartStack partStack = (MPartStack) mPartSashContainerElement;
List<MStackElement> children2 = partStack.getChildren();
for (MStackElement mStackElement : children2) {
if (mStackElement instanceof MPart) {
MPart part = (MPart) mStackElement;
// Library is the Editor Name wiche I want to move
if (part.getLabel().equals("Library")) {
partToMove = part;
break;
}
}
}
}
}
}
}
if (partToMove != null) {
moveElement(modelService, application, partToMove);
}
}
private static void moveElement(EModelService modelService,
MApplication application, MPart part) {
// target PartStack
MUIElement find = modelService.find("de.bsg.onesps.rcp.
partstack.library", application);
if (find instanceof MPartStack) {
MPartStack mPartStack = (MPartStack) find;
mPartStack.getChildren().add(part);
mPartStack.setSelectedElement(part);
}
}

In AEM6, How do I hide a specific component field based on pages for certain country only?

In AEM6, How do I hide a specific component field based on pages for certain country only ?
You can write custom dialog/widget plugin to do that. This is how you attach plugin to your widget:
<title jcr:primaryType="cq:Widget"
fieldLabel="Field to hide"
plugins="hideFieldPlugin"
name="./fieldToHide"
xtype="textfield" />
Next, we need to write plugin and register it:
(function ($) {
var plugin = CQ.Ext.extend(CQ.Ext.emptyFn, {
init: function (fieldToHide) {
var url = CQ.HTTP.getPath();
if (this.shouldBeHidden(url)) {
fieldToHide.hide().disable();
}
},
shouldBeHidden: function (url) {
// some logic
return true;
}
});
CQ.Ext.ComponentMgr.registerPlugin("hideFieldPlugin", plugin);
}($CQ));
JavaScript file needs to be included in Classic UI edit mode. Best way to do that is to use your own custom clientlib or use already existing category, cq.wcm.edit.
If you have more complex logic which goes across multiple widgets, you can attach plugin on dialog level and navigate to the widget objects using dialog.find method.

App crashes on exit when using ListFragment called from a Sliding Tab's Fragment adapter

I have spend almost two day trying to figure out why this is happening but couldn't find a solution so far. So I am posting it here.
I have a pretty generic Sliding Tab which is created in Eclipse for newer Android APIs. Inside one of the sliding tabs I call a ListFragment. This ListFragment uses CursorLoader to load some data.
Now when the app exits, it gives: 05-28 11:34:00.327: E/AndroidRuntime(31994): java.lang.RuntimeException: Unable to destroy activity {com.example.myapp/com.example.myapp.main.HomeActivity}: java.lang.NullPointerException
I have tried using ChildFragmentManager and also the latest support package, but to no avail.
This is the only tab which calls another fragment, otherwise rest of the tabs which just call static XML content work just fine. App works fine if I remove this tab.
As I understand I need to destroy the CursorLoader or somehow detach this particular fragment before the app exits. CursorLoader seems to get destroyed, and the error is caught in HomeActivty. Maybe I should call onDestroy in HomeActivity, but really don't know how and where exactly.
Code of the calling HomeActivity is pretty standard:
ViewPager mViewPager;
private static final String DEBUG_TAG = "MY APP";
private static boolean logged_in;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
logged_in = sharedPrefs.getBoolean("logged_in", false);
Log.v(DEBUG_TAG, "logged_in: " + logged_in);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.home, menu);
return true;
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment;
switch(position) {
case 0:
fragment = new MySectionFragment();
break;
case 1:
...
The code which calls the ListFragment from the FragmentActivity is as follows:
public static class MySectionFragment extends Fragment {
public MySectionFragment() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_my_section, container, false);
}
public void onDestroyView() {
super.onDestroyView();
Fragment fragment = (getFragmentManager().findFragmentById(R.id.fragment_my_section));
if (fragment != null) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commitAllowingStateLoss();
}
}
}
Finally I found the answer and it was in the most unexpected place in the code. I still don't understand the mechanics, but I have confirmed throughly that it works.
I am using Android 4.0.3 with support library rev 12.
Turned out that my code was perfectly fine and I didn't even need onDestroyView(). Views get destroyed and regenerated fine. There was no need to deal with FragmentManager, SupportFragmentManager or ChildSupportFragmentManager. The default code which is generated in Eclipse when selecting swipable tabs is just fine.
The only place where I made a change, which fixed it all was the XML template. I moved the android:id from 'fragment' section to 'RelativeLayout' section.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/fragment_my_section"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="4dp"
android:background="#drawable/bg">
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false"
android:cacheColorHint="#00000000"/>
<fragment
android:name="com.example.MyFragmentActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</fragment>
</RelativeLayout>
Previously the id was in the 'fragment' section. This was when there was no RelativeLayout and ListView defined in the XML file.
Needless to say I hate XMLs in this Android development world. Majority of the time it has always been an XML file which has wasted my time, without an exception. IDEs don't catch these XML issues well either. I wish Android development get rid or XMLs altogether..

Remove "File, edit,...etc" menus from Eclipse RCP application

I want to remove the File, edit, Source, Refactor, etc. menus from my RCP application
Can I use hideActionSet() ? or what should I do ?
That's right; in your ApplicationWorkbenchWindowAdvisor, override postWindowOpen().
The tricky bit is usually figuring out the names of the actionsets that you want to remove, but you can use the old standby ALT-SHIFT-F2 (the default keybinding for 'Plugin-in Menu Spy') and click on one of the menu items that you want to remove.
Note that if the menu item is disabled, the spy won't give you any info on it.
public void postWindowOpen() {
runApplicationWorkbenchDelegate();
// remove unwanted UI contributions that eclipse makes by default
IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows();
for (int i = 0; i < windows.length; ++i) {
IWorkbenchPage page = windows[i].getActivePage();
if (page != null) {
// hide generic 'File' commands
page.hideActionSet("org.eclipse.ui.actionSet.openFiles");
// hide 'Convert Line Delimiters To...'
page.hideActionSet("org.eclipse.ui.edit.text.actionSet.convertLineDelimitersTo");
// hide 'Search' commands
page.hideActionSet("org.eclipse.search.searchActionSet");
// hide 'Annotation' commands
page.hideActionSet("org.eclipse.ui.edit.text.actionSet.annotationNavigation");
// hide 'Forward/Back' type navigation commands
page.hideActionSet("org.eclipse.ui.edit.text.actionSet.navigation");
}
}
}
Although the question is old:
Lars Vogel's tutorial about Eclipse Activities shows how to hide entire menus in an RCP application rather than removing single menu-entries.
EDIT:
Alternatively you can use the MenuManager attached to the workbench window to show or hide Menus/Contributions.
Try the following code to hide all menus:
WorkbenchWindow workbenchWin = (WorkbenchWindow)PlatformUI.getWorkbench().getActiveWorkbenchWindow();
MenuManager menuManager = workbenchWin.getMenuManager();
IContributionItem[] items = menuManager.getItems();
for(IContributionItem item : items) {
item.setVisible(false);
}