The goal is to implement the following functionality. Three EditText fields. Each of them should be filled with its custom keyboard.
1. English
2. Russian
3. transcription
Keyboards I implemented with the help of this class
public class CustomKeyboard {
/** A link to the KeyboardView that is used to render this CustomKeyboard. */
private KeyboardView mKeyboardView;
/** A link to the activity that hosts the {#link #mKeyboardView}. */
private Activity mHostActivity;
/** The key (code) handler. */
private OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() {
public final static int CodeDelete = -5; // Keyboard.KEYCODE_DELETE
public final static int CodeCancel = -3; // Keyboard.KEYCODE_CANCEL
public final static int CodePrev = 55000;
public final static int CodeAllLeft = 55001;
public final static int CodeLeft = 55002;
public final static int CodeRight = 55003;
public final static int CodeAllRight = 55004;
public final static int CodeNext = 55005;
public final static int CodeClear = 55006;
#Override public void onKey(int primaryCode, int[] keyCodes) {
// NOTE We can say '<Key android:codes="49,50" ... >' in the xml file; all codes come in keyCodes, the first in this list in primaryCode
// Get the EditText and its Editable
View focusCurrent = mHostActivity.getWindow().getCurrentFocus();
if( focusCurrent==null || focusCurrent.getClass()!=EditText.class ) return;
EditText edittext = (EditText) focusCurrent;
Editable editable = edittext.getText();
int start = edittext.getSelectionStart();
// Apply the key to the edittext
if( primaryCode==CodeCancel ) {
hideCustomKeyboard();
} else if( primaryCode==CodeDelete ) {
if( editable!=null && start>0 ) editable.delete(start - 1, start);
} else if( primaryCode==CodeClear ) {
if( editable!=null ) editable.clear();
} else if( primaryCode==CodeLeft ) {
if( start>0 ) edittext.setSelection(start - 1);
} else if( primaryCode==CodeRight ) {
if (start < edittext.length()) edittext.setSelection(start + 1);
} else if( primaryCode==CodeAllLeft ) {
edittext.setSelection(0);
} else if( primaryCode==CodeAllRight ) {
edittext.setSelection(edittext.length());
} else if( primaryCode==CodePrev ) {
View focusNew= edittext.focusSearch(View.FOCUS_BACKWARD);
if( focusNew!=null ) focusNew.requestFocus();
} else if( primaryCode==CodeNext ) {
View focusNew= edittext.focusSearch(View.FOCUS_FORWARD);
if( focusNew!=null ) focusNew.requestFocus();
} else { // insert character
editable.insert(start, Character.toString((char) primaryCode));
}
}
#Override public void onPress(int arg0) {
}
#Override public void onRelease(int primaryCode) {
}
#Override public void onText(CharSequence text) {
}
#Override public void swipeDown() {
}
#Override public void swipeLeft() {
}
#Override public void swipeRight() {
}
#Override public void swipeUp() {
}
};
/**
* Create a custom keyboard, that uses the KeyboardView (with resource id <var>viewid</var>) of the <var>host</var> activity,
* and load the keyboard layout from xml file <var>layoutid</var> (see {#link Keyboard} for description).
* Note that the <var>host</var> activity must have a <var>KeyboardView</var> in its layout (typically aligned with the bottom of the activity).
* Note that the keyboard layout xml file may include key codes for navigation; see the constants in this class for their values.
* Note that to enable EditText's to use this custom keyboard, call the {#link #registerEditText(int)}.
*
* #param host The hosting activity.
* #param viewid The id of the KeyboardView.
* #param layoutid The id of the xml file containing the keyboard layout.
*/
public CustomKeyboard(Activity host, int viewid, int layoutid) {
mHostActivity= host;
mKeyboardView= (KeyboardView)mHostActivity.findViewById(viewid);
mKeyboardView.setKeyboard(new Keyboard(mHostActivity, layoutid));
mKeyboardView.setPreviewEnabled(false); // NOTE Do not show the preview balloons
mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);
// Hide the standard keyboard initially
mHostActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
/** Returns whether the CustomKeyboard is visible. */
public boolean isCustomKeyboardVisible() {
return mKeyboardView.getVisibility() == View.VISIBLE;
}
/** Make the CustomKeyboard visible, and hide the system keyboard for view v. */
public void showCustomKeyboard( View v ) {
mKeyboardView.setVisibility(View.VISIBLE);
mKeyboardView.setEnabled(true);
if( v!=null ) ((InputMethodManager)mHostActivity.getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
}
/** Make the CustomKeyboard invisible. */
public void hideCustomKeyboard() {
mKeyboardView.setVisibility(View.GONE);
mKeyboardView.setEnabled(false);
}
/**
* Register <var>EditText<var> with resource id <var>resid</var> (on the hosting activity) for using this custom keyboard.
*
* #param resid The resource id of the EditText that registers to the custom keyboard.
*/
public void registerEditText(int resid) {
// Find the EditText 'resid'
//TextInputEditText edittext= (TextInputEditText)mHostActivity.findViewById(resid);
EditText edittext= (EditText)mHostActivity.findViewById(resid);
// Make the custom keyboard appear
edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
// NOTE By setting the on focus listener, we can show the custom keyboard when the edit box gets focus, but also hide it when the edit box loses focus
#Override public void onFocusChange(View v, boolean hasFocus) {
if( hasFocus ) showCustomKeyboard(v); else hideCustomKeyboard();
}
});
edittext.setOnClickListener(new OnClickListener() {
// NOTE By setting the on click listener, we can show the custom keyboard again, by tapping on an edit box that already had focus (but that had the keyboard hidden).
#Override public void onClick(View v) {
showCustomKeyboard(v);
}
});
// Disable standard keyboard hard way
// NOTE There is also an easy way: 'edittext.setInputType(InputType.TYPE_NULL)' (but you will not have a cursor, and no 'edittext.setCursorVisible(true)' doesn't work )
edittext.setOnTouchListener(new OnTouchListener() {
#Override public boolean onTouch(View v, MotionEvent event) {
EditText edittext = (EditText) v;
int inType = edittext.getInputType(); // Backup the input type
edittext.setInputType(InputType.TYPE_NULL); // Disable standard keyboard
edittext.onTouchEvent(event); // Call native handler
edittext.setInputType(inType); // Restore input type
return true; // Consume touch event
}
});
// Disable spell check (hex strings look like words to Android)
edittext.setInputType(edittext.getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
}
}
and three different xml-layouts
The Activity I create three copies keyboard class. With different layouts. Register each of them their field.
public class WordsListActivity extends Activity {
public static final String LOG_TAG = "WordsListActivity";
protected RecyclerView mRecyclerView;
protected Button btnAddWord;
protected WordViewAdapter mAdapter;
protected RecyclerView.LayoutManager mLayoutManager;
protected WordsListActivity.LayoutManagerType mCurrentLayoutManagerType;
protected List<Word> wordsList;
protected int categoryId;
protected CustomKeyboard mCustomKeyboardEN, mCustomKeyboardRU, mCustomKeyboardTrancroption;
protected ForegroundLinearLayout addWordLyout;
protected Button okButton, cancelButton;
protected EditText etWordOrigin, etWordTranslate, etWordTranscription;
private enum LayoutManagerType {
GRID_LAYOUT_MANAGER,
LINEAR_LAYOUT_MANAGER
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_words_list);
Intent intent = getIntent();
categoryId = (int) intent.getLongExtra("categoryId",0);
View rootView = getLayoutInflater().inflate(R.layout.content_main, null).getRootView();
mRecyclerView = (RecyclerView)findViewById(R.id.wrodsRecyclerView);
btnAddWord = (Button)findViewById(R.id.btnAddNewWord);
mLayoutManager = new LinearLayoutManager(this);
mCurrentLayoutManagerType = WordsListActivity.LayoutManagerType.LINEAR_LAYOUT_MANAGER;
setRecyclerViewLayoutManager(mCurrentLayoutManagerType);
addWordLyout =(ForegroundLinearLayout)findViewById(R.id.inputWordLayout);
addWordLyout.setVisibility(View.INVISIBLE);
etWordOrigin = (EditText)findViewById(R.id.etWordOrigin);
etWordTranslate = (EditText)findViewById(R.id.etWordTranslate);
etWordTranscription = (EditText)findViewById(R.id.etWordTrancription);
okButton = (Button) findViewById(R.id.addButton);
cancelButton = (Button) findViewById(R.id.cancelButton);
/* creting keybords*/
mCustomKeyboardRU = new CustomKeyboard(this, R.id.keyboardviewWords, R.xml.kbd_ru);//russian
mCustomKeyboardRU.registerEditText(R.id.etWordOrigin);
mCustomKeyboardEN = new CustomKeyboard(this, R.id.keyboardviewWords, R.xml.kbd_en);//english
mCustomKeyboardEN.registerEditText(R.id.etWordTranslate);
/*in all EditText field showing this last keyboard copy*/
mCustomKeyboardTrancroption = new CustomKeyboard(this, R.id.keyboardviewWords, R.xml.kbd_transcription);//transcription
mCustomKeyboardTrancroption.registerEditText(R.id.etWordTrancription);
btnAddWord.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addWordLyout.setVisibility(View.VISIBLE);
}
});
}
#Override public void onBackPressed() {
// NOTE Trap the back key: when the CustomKeyboard is still visible hide it, only when it is invisible, finish activity
if( mCustomKeyboardRU.isCustomKeyboardVisible() ) mCustomKeyboardRU.hideCustomKeyboard(); else this.finish();
}
public void setRecyclerViewLayoutManager(WordsListActivity.LayoutManagerType layoutManagerType) {
/*
mLayoutManager = new GridLayoutManager(this, SPAN_COUNT);
mCurrentLayoutManagerType = LayoutManagerType.GRID_LAYOUT_MANAGER;*/
mLayoutManager = new LinearLayoutManager(this);
mCurrentLayoutManagerType = WordsListActivity.LayoutManagerType.LINEAR_LAYOUT_MANAGER;
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.scrollToPosition(0);
initDataset();
}
private void initDataset() {
wordsList = new DataBase(this).getWordsList(categoryId);
mAdapter = new WordViewAdapter(wordsList, this);
mRecyclerView.setAdapter(mAdapter);
if(wordsList.size()==0){
Toast.makeText(this, "nothing to Show", Toast.LENGTH_LONG).show();
}
}
}
but when you run applications with focus on all fields it shows the last keyboard. in this case transcription.
Related
I have 3 AutoCompleteTextView and I want to make a simple function to detect whenever it gain/loses focus so I'll hide an imageView.
Or maybe, whenever the keyboard is UP I want to hide my logo (imageView). When the keyboard is down, show the imageView again.
Code so far:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
RelativeLayout layout = (RelativeLayout)findViewById(R.id.mainLayout);
for(int i=0; i< layout.getChildCount(); i++) {
View v = layout.getChildAt(i);
if(v instanceof AutoCompleteTextView) {
v.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
// if(hasWindowFocus()) {
// ImageView logo = findViewById(R.id.imgLogo);
// logo.setVisibility(View.GONE);
// }
Toast.makeText(getApplicationContext(), "pimba", Toast.LENGTH_LONG).show();
}
});
}
}
}
Also, is it possible to create listeners outside this onCreate() ? Or creating everything inside this function is the right way to go?
Try this
Solution 1
Call this method in onCreate()
private void initKeyBoardListener() {
//Threshold for minimal keyboard height.
final int MIN_KEYBOARD_HEIGHT_PX = 150;
//Top-level window decor view.
final View decorView = getWindow().getDecorView();
// Register global layout listener.
decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
// Retrieve visible rectangle inside window.
private final Rect windowVisibleDisplayFrame = new Rect();
private int lastVisibleDecorViewHeight;
#Override
public void onGlobalLayout() {
decorView.getWindowVisibleDisplayFrame(windowVisibleDisplayFrame);
final int visibleDecorViewHeight = windowVisibleDisplayFrame.height();
if (lastVisibleDecorViewHeight != 0) {
if (lastVisibleDecorViewHeight > visibleDecorViewHeight + MIN_KEYBOARD_HEIGHT_PX) {
Log.d("Keyboard", "SHOW");
// Hide imageview
} else if (lastVisibleDecorViewHeight + MIN_KEYBOARD_HEIGHT_PX < visibleDecorViewHeight) {
// Show imageview
Log.d("Keyboard", "HIDE");
}
}
// Save current decor view height for the next call.
lastVisibleDecorViewHeight = visibleDecorViewHeight;
}
});
}
Solution 2
Use this Util class
import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import java.util.HashMap;
/**
* Created by Raman on 2/10/2017.
*/
public class KeyboardUtils implements ViewTreeObserver.OnGlobalLayoutListener {
private static HashMap<SoftKeyboardToggleListener, KeyboardUtils> sListenerMap = new HashMap<>();
private SoftKeyboardToggleListener mCallback;
private View mRootView;
private float mScreenDensity = 1;
private KeyboardUtils(Activity act, SoftKeyboardToggleListener listener) {
mCallback = listener;
mRootView = ((ViewGroup) act.findViewById(android.R.id.content)).getChildAt(0);
mRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
mScreenDensity = act.getResources().getDisplayMetrics().density;
}
public static void addKeyboardToggleListener(Activity act, SoftKeyboardToggleListener listener) {
removeKeyboardToggleListener(listener);
sListenerMap.put(listener, new KeyboardUtils(act, listener));
}
public static void removeKeyboardToggleListener(SoftKeyboardToggleListener listener) {
if (sListenerMap.containsKey(listener)) {
KeyboardUtils k = sListenerMap.get(listener);
k.removeListener();
sListenerMap.remove(listener);
}
}
public static void removeAllKeyboardToggleListeners() {
for (SoftKeyboardToggleListener l : sListenerMap.keySet())
sListenerMap.get(l).removeListener();
sListenerMap.clear();
}
#Override
public void onGlobalLayout() {
Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
mRootView.getWindowVisibleDisplayFrame(r);
int heightDiff = mRootView.getRootView().getHeight() - (r.bottom - r.top);
float dp = heightDiff / mScreenDensity;
if (mCallback != null)
mCallback.onToggleSoftKeyboard(dp > 200);
}
private void removeListener() {
mCallback = null;
mRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
public interface SoftKeyboardToggleListener {
void onToggleSoftKeyboard(boolean isVisible);
}
}
And its usage
Call this in onCreate()
KeyboardUtils.addKeyboardToggleListener(getActivity(), new KeyboardUtils.SoftKeyboardToggleListener() {
#Override
public void onToggleSoftKeyboard(boolean isVisible) {
Log.d("keyboard", "keyboard visible: " + isVisible);
if (!isVisible) {
// show imageview
}
else
{
// hide imageview
}
}
});
I've been working on google's course sunshine app and wanted to put my personal touch in it so i made the user specify his city by using a hybrid of EditTextPreference and AutoCompleteTextView shown in here:
public class AutoCompleteEditTextPreference extends EditTextPreference {
private static String[] list;
private boolean isValid = true;
private Dialog dialog;
public AutoCompleteEditTextPreference(Context context) {
super(context);
}
public AutoCompleteEditTextPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AutoCompleteEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* the default EditTextPreference does not make it easy to
* use an AutoCompleteEditTextPreference field. By overriding this method
* we perform surgery on it to use the type of edit field that
* we want.
*/
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
// find the current EditText object
final EditText editText = (EditText) view.findViewById(android.R.id.edit);
// copy its layout params
ViewGroup.LayoutParams params = editText.getLayoutParams();
ViewGroup vg = (ViewGroup) editText.getParent();
String curVal = editText.getText().toString();
// remove it from the existing layout hierarchy
vg.removeView(editText);
// construct a new editable autocomplete object with the appropriate params
// and id that the TextEditPreference is expecting
mACTV = new AutoCompleteTextView(getContext());
mACTV.setLayoutParams(params);
mACTV.setId(android.R.id.edit);
mACTV.setText(curVal);
Arrays.sort(list);
isValid = isValid(mACTV.getText().toString());
mACTV.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
isValid = isValid(s.toString());
validate();
}
});
mACTV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
isValid = isValid(mACTV.getText().toString());
validate();
}
});
ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(),
android.R.layout.simple_dropdown_item_1line, list);
mACTV.setAdapter(adapter);
// add the new view to the layout
vg.addView(mACTV);
}
private boolean isValid(CharSequence text) {
return !text.equals("") && Arrays.binarySearch(list, text.toString()) > 0;
}
#Override
protected void showDialog(Bundle state) {
super.showDialog(state);
validate();
}
private void validate() {
dialog = getDialog();
Toast.makeText(getContext(), Boolean.toString(dialog instanceof AlertDialog), Toast.LENGTH_SHORT).show();
if (dialog instanceof AlertDialog) {
Button btn = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
btn.setEnabled(isValid);
}
}
/**
* Because the baseclass does not handle this correctly
* we need to query our injected AutoCompleteTextView for
* the value to save
*/
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult && mACTV != null) {
String value = mACTV.getText().toString();
if (callChangeListener(value))
setText(value);
}
}
static void prepareCountriesList(Context context) {
List<String> lines = new ArrayList<>();
try {
InputStream inputStream = context.getAssets().open("cities.txt");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = bufferedReader.readLine()) != null) {
lines.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
list = lines.toArray(new String[lines.size()]);
}
/**
* again we need to override methods from the base class
*/
public EditText getEditText() {
return mACTV;
}
private AutoCompleteTextView mACTV = null;
private final String TAG = "AutoCompleteEditTextPreference";
}
so everything was going great until the last part where i wanted to disable the ok button
private void validate() {
dialog = getDialog();
Toast.makeText(getContext(), Boolean.toString(dialog instanceof AlertDialog), Toast.LENGTH_SHORT).show();
if (dialog instanceof AlertDialog) {
Button btn = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
btn.setEnabled(isValid);
}
}
so i try the method getDialog();
and it returns a dialog that is not null and not an instance of AlertDialog
anyhelp please on getting the dialog properly or another way to disable the ok button programmatically
It's ok found the problem;
it was that i used
import android.support.v7.app.AlertDialog;
instead of
import android.app.AlertDialog;
thanks for anyone who tried to help
import org.alljoyn.bus.sample.chat.ChatApplication;
import org.alljoyn.bus.sample.chat.Observable;
import org.alljoyn.bus.sample.chat.Observer;
import org.alljoyn.bus.sample.chat.DialogBuilder;
import java.lang.reflect.Array;
// ... more imports
public class UseActivity extends Activity implements Observer {
private static final String TAG = "chat.UseActivity";
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.use);
ListView hlv = (ListView) findViewById(R.id.useHistoryList);
hlv.setAdapter(mHistoryList);
EditText messageBox = (EditText)findViewById(R.id.useMessage);
messageBox.setSingleLine();
messageBox.setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
message = view.getText().toString();
Log.i(TAG, "useMessage.onEditorAction(): got message " + message + ")");
mHistoryList.add(message);
mChatApplication.newLocalUserMessage(message);
view.setText("");
}
return true;
}
});
Button mAlertButton = (Button)findViewById(R.id.alert);
mAlertButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
message = "www.google.com" ;
mHistoryList.add(message);
mChatApplication.newLocalUserMessage(message);
}
});
mJoinButton = (Button)findViewById(R.id.useJoin);
mJoinButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
showDialog(DIALOG_JOIN_ID);
}
});
mLeaveButton = (Button)findViewById(R.id.useLeave);
mLeaveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
showDialog(DIALOG_LEAVE_ID);
}
});
mChannelName = (TextView)findViewById(R.id.useChannelName);
mChannelStatus = (TextView)findViewById(R.id.useChannelStatus);
/*
* Keep a pointer to the Android Application class around. We use this
* as the Model for our MVC-based application. Whenever we are started
* we need to "check in" with the application so it can ensure that our
* required services are running.
*/
mChatApplication = (ChatApplication)getApplication();
mChatApplication.checkin();
/*
* Call down into the model to get its current state. Since the model
* outlives its Activities, this may actually be a lot of state and not
* just empty.
*/
updateChannelState();
updateHistory();
/*
* Now that we're all ready to go, we are ready to accept notifications
* from other components.
*/
mChatApplication.addObserver(this);
}
public void onDestroy() {
Log.i(TAG, "onDestroy()");
mChatApplication = (ChatApplication)getApplication();
mChatApplication.deleteObserver(this);
super.onDestroy();
}
public static final int DIALOG_JOIN_ID = 0;
public static final int DIALOG_LEAVE_ID = 1;
public static final int DIALOG_ALLJOYN_ERROR_ID = 2;
protected Dialog onCreateDialog(int id) {
Log.i(TAG, "onCreateDialog()");
Dialog result = null;
switch(id) {
case DIALOG_JOIN_ID:
{
DialogBuilder builder = new DialogBuilder();
result = builder.createUseJoinDialog(this, mChatApplication);
}
break;
case DIALOG_LEAVE_ID:
{
DialogBuilder builder = new DialogBuilder();
result = builder.createUseLeaveDialog(this, mChatApplication);
}
break;
case DIALOG_ALLJOYN_ERROR_ID:
{
DialogBuilder builder = new DialogBuilder();
result = builder.createAllJoynErrorDialog(this, mChatApplication);
}
break;
}
return result;
}
public synchronized void update(Observable o, Object arg) {
Log.i(TAG, "update(" + arg + ")");
String qualifier = (String)arg;
if (qualifier.equals(ChatApplication.APPLICATION_QUIT_EVENT)) {
Message message = mHandler.obtainMessage(HANDLE_APPLICATION_QUIT_EVENT);
mHandler.sendMessage(message);
}
if (qualifier.equals(ChatApplication.HISTORY_CHANGED_EVENT)) {
Message message = mHandler.obtainMessage(HANDLE_HISTORY_CHANGED_EVENT);
mHandler.sendMessage(message);
}
if (qualifier.equals(ChatApplication.USE_CHANNEL_STATE_CHANGED_EVENT)) {
Message message = mHandler.obtainMessage(HANDLE_CHANNEL_STATE_CHANGED_EVENT);
mHandler.sendMessage(message);
}
if (qualifier.equals(ChatApplication.ALLJOYN_ERROR_EVENT)) {
Message message = mHandler.obtainMessage(HANDLE_ALLJOYN_ERROR_EVENT);
mHandler.sendMessage(message);
}
}
private void updateHistory() {
Log.i(TAG, "updateHistory()");
List <String> messages = mChatApplication.getHistory();
mHistoryList = new SimpleAdapter (this, messages);
for (String message : messages) {
mHistoryList.add(message);
}
mHistoryList.notifyDataSetChanged();
}
private void updateChannelState() {
Log.i(TAG, "updateHistory()");
AllJoynService.UseChannelState channelState = mChatApplication.useGetChannelState();
String name = mChatApplication.useGetChannelName();
if (name == null) {
name = "Not set";
}
mChannelName.setText(name);
switch (channelState) {
case IDLE:
mChannelStatus.setText("Idle");
mJoinButton.setEnabled(true);
mLeaveButton.setEnabled(false);
break;
case JOINED:
mChannelStatus.setText("Joined");
mJoinButton.setEnabled(false);
mLeaveButton.setEnabled(true);
break;
}
}
/**
* An AllJoyn error has happened. Since this activity pops up first we
* handle the general errors. We also handle our own errors.
*/
private void alljoynError() {
if (mChatApplication.getErrorModule() == ChatApplication.Module.GENERAL ||
mChatApplication.getErrorModule() == ChatApplication.Module.USE) {
showDialog(DIALOG_ALLJOYN_ERROR_ID);
}
}
private static final int HANDLE_APPLICATION_QUIT_EVENT = 0;
private static final int HANDLE_HISTORY_CHANGED_EVENT = 1;
private static final int HANDLE_CHANNEL_STATE_CHANGED_EVENT = 2;
private static final int HANDLE_ALLJOYN_ERROR_EVENT = 3;
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case HANDLE_APPLICATION_QUIT_EVENT:
{
Log.i(TAG, "mHandler.handleMessage(): HANDLE_APPLICATION_QUIT_EVENT");
finish();
}
break;
case HANDLE_HISTORY_CHANGED_EVENT:
{
Log.i(TAG, "mHandler.handleMessage(): HANDLE_HISTORY_CHANGED_EVENT");
updateHistory();
break;
}
case HANDLE_CHANNEL_STATE_CHANGED_EVENT:
{
Log.i(TAG, "mHandler.handleMessage(): HANDLE_CHANNEL_STATE_CHANGED_EVENT");
updateChannelState();
break;
}
case HANDLE_ALLJOYN_ERROR_EVENT:
{
Log.i(TAG, "mHandler.handleMessage(): HANDLE_ALLJOYN_ERROR_EVENT");
alljoynError();
break;
}
default:
break;
}
}
};
private ChatApplication mChatApplication = null;
String message;
private SimpleAdapter mHistoryList;
private Button mJoinButton;
private Button mLeaveButton;
private TextView mChannelName;
private TextView mChannelStatus;
}
I'm having some troubles getting my custom listView adapter to work. I am having issue in getting the message values dynamically into the custom adapter. I have got the values dynamically but when I used that in my code, the app crashes or it displays nothing.
import android.text.util.Linkify;
// ... more imports
public class SimpleAdapter extends ArrayAdapter<String> {
private final Context context;
private final List<String> values;
public SimpleAdapter(Context context, List <String> values) {
super(context, -1, values);
this.context = context;
this.values = values;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.view, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.text);
textView.setText(values.get(position));
Linkify.addLinks(textView,Linkify.WEB_URLS);
return rowView;
}
}
I was wondering how to start a new intent if the user presses a button in my Android in-app tutorial (ShowcaseViews). Here is my ShowcaseViews class:
public class ShowcaseViews {
private final List<ShowcaseView> views = new ArrayList<ShowcaseView>();
private final Activity activity;
private final int showcaseTemplateId;
private interface OnShowcaseAcknowledged {
void onShowCaseAcknowledged(ShowcaseView oldView);
}
/**
* #param activity The activity containing the views you wish to showcase
* #param showcaseTemplateLayout Must be the layout of a ShowcaseView - use this to style your showcase
*/
public ShowcaseViews(Activity activity, int showcaseTemplateLayout) {
this.activity = activity;
this.showcaseTemplateId = showcaseTemplateLayout;
}
public void addView(ItemViewProperties properties) {
ShowcaseView viewTemplate = newInstanceOfShowcaseView();
viewTemplate.setShowcaseItem(properties.itemType, properties.id, activity);
viewTemplate.setText(properties.titleResId, properties.messageResId);
setChainClickListener(viewTemplate);
views.add(viewTemplate);
}
public void addView(ViewProperties properties) {
ShowcaseView viewTemplate = newInstanceOfShowcaseView();
View v = activity.findViewById(properties.id);
viewTemplate.setShowcaseView(v);
viewTemplate.setText(properties.titleResId, properties.messageResId);
setChainClickListener(viewTemplate);
views.add(viewTemplate);
}
private ShowcaseView newInstanceOfShowcaseView() {
return (ShowcaseView) activity.getLayoutInflater().inflate(showcaseTemplateId, null);
}
private void setChainClickListener(final ShowcaseView viewTemplate) {
viewTemplate.overrideButtonClick(new View.OnClickListener() {
#Override
public void onClick(View v) {
acknowledgedListener.onShowCaseAcknowledged(viewTemplate);
}
});
}
private OnShowcaseAcknowledged acknowledgedListener = new OnShowcaseAcknowledged() {
#Override
public void onShowCaseAcknowledged(ShowcaseView oldView) {
oldView.hide();
show();
}
};
/**
* Showcases will be shown in the order they where added, continuing when the button is pressed
*/
public void show() {
if (views.isEmpty()) {
return;
}
final ShowcaseView view = views.get(0);
((ViewGroup) activity.getWindow().getDecorView()).addView(view);
views.remove(0);
}
/**
* Used for views on the ActionBar
*/
public static class ItemViewProperties extends ViewProperties {
public static final int ID_SPINNER = 0;
public static final int ID_TITLE = 0;
protected final int itemType;
public ItemViewProperties(int id, int titleResId, int messageResId, int itemType) {
super(id, titleResId, messageResId);
this.itemType = itemType;
}
}
/**
* Used for all views except those on the ActionBar
*/
public static class ViewProperties {
protected final int titleResId;
protected final int messageResId;
protected final int id;
public ViewProperties(int id, int titleResId, int messageResId) {
this.id = id;
this.titleResId = titleResId;
this.messageResId = messageResId;
}
}
}
Here is my MainActivity class:
public void showcaseSecondActivity() {
ShowcaseViews views = new ShowcaseViews(CameraTestActivity.this, R.layout.view_showcase);
views.addView(new ShowcaseViews.ItemViewProperties(0, R.string.showcase_main_spinner_title, R.string.showcase_main_spinner_message, ShowcaseView.ITEM_ACTION_HOME));
Intent intent = new Intent(CameraTestActivity.this, UserSettingsActivity.class);
views.show();
}
Here is my view_showcase XML file:
<?xml version="1.0" encoding="utf-8"?>
<!-- This is our ShowCase template that we will use
whenever we want to showcase an item.
Here we can customise the colors of the showcase. -->
<com.rohit.ShowcaseView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:showcaseview="http://schemas.android.com/apk/res/com.rohit"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
showcaseview:sv_backgroundColor="#color/showcase_background"
showcaseview:sv_buttonText="#string/showcase_button_ok" />
If I add startActivity(intent) after views.show() in my MainActivity class, it doesn't even show the dialog and goes straight to the intent. I want to open the activity AFTER the user has clicked the button. I don't know to proceed. I am quite new to this and I have searched all over SO and Google. Any help regarding this problem would be appreciated.
showcaseView.setOnShowcaseEventListener(new OnShowcaseEventListener() {
#Override
public void onShowcaseViewShow(ShowcaseView arg0) { }
#Override
public void onShowcaseViewHide(ShowcaseView arg0) {
Intent i = new Intent(SignIn.this,MainFragmentActivity.class);
startActivity(i);
}
#Override
public void onShowcaseViewDidHide(ShowcaseView arg0) { }
});
I have implemented list view having buttons having background image changing effects.but, when I tap on any list item, that effect is no longer present there and get refreshed.
I checked that, when I tap on any list item, that getView() is calling...
How to avoid this???
please suggest any solution if anyone knows...
Thank you..
code is :
public class EventListAdapter extends BaseAdapter {
private static final int VISIBLE = 0;
private static final int GONE = 8;
private List<Events> dateForEventList;
private String eventsRetrived;
private String[] events;
boolean clickStatus = false;
private int status = 0;
public EventListAdapter(Context context)
{
mContext = context;
}
/**
* The number of items in the list is determined by the number of announcements
* in our array.
*
* #see android.widget.ListAdapter#getCount()
*/
public int getCount() {
DatabaseManager db = new DatabaseManager(mContext);
dateForEventList = db.getAllData1(CalendarAdapter.dateOfEventSingle);
for (Events l : dateForEventList) {
eventsRetrived = l.getEventData();
}
events = eventsRetrived.split(",");
return events.length;
}
/**
* Since the data comes from an array, just returning
* the index is sufficent to get at the data. If we
* were using a more complex data structure, we
* would return whatever object represents one
* row in the list.
*
* #see android.widget.ListAdapter#getItem(int)
*/
public Object getItem(int position) {
return position;
}
/**
* Use the array index as a unique id.
* #see android.widget.ListAdapter#getItemId(int)
*/
public long getItemId(int position) {
return position;
}
public View getView(final int position, View myView, ViewGroup parent) {
if(myView == null) {
LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
myView = inflater.inflate(R.layout.activity_event_list, null);
}
TextView textViewTitle;
TextView textViewDialogue;
final ImageButton buttonForCheckMark;
final ImageButton buttonForDelete;
final ImageButton buttonForRemainder;
//Events event = new Events("11/2/2013","today, there is function in Shivajinagar");
// event.setDate("11 Jan,2013");
// String event1 = event.getDate();
//
// textViewForDateHeader = (TextView)myView.findViewById(R.id.textViewHeadingDate);
// textViewForDateHeader.setText(event1);
DatabaseManager db = new DatabaseManager(mContext);
dateForEventList = db.getAllData1(CalendarAdapter.dateOfEventSingle);
for (Events l : dateForEventList) {
eventsRetrived = l.getEventData();
}
events = eventsRetrived.split(",");
// TextView tv = (TextView)myView.findViewById(R.id.grid_item_text);
// tv.setText(events[position]);
textViewTitle = (TextView) myView.findViewById(R.id.textViewTitle);
textViewTitle.setText(events[position]);
textViewDialogue = (TextView) myView.findViewById(R.id.textViewDialog);
textViewDialogue.setText(events[position]);
textViewDialogue.setVisibility(mExpanded[position] ? VISIBLE : GONE);
// textViewHeader = (TextView)myView.findViewById(R.id.textViewHeader);
// textViewHeader.setText(mHeader[position]);
// textViewHeader.setVisibility(mExpanded[position] ? VISIBLE : GONE);
buttonForCheckMark = (ImageButton) myView.findViewById(R.id.buttonForCheckMark);
buttonForCheckMark.setVisibility(mExpanded[position] ? VISIBLE : GONE);
buttonForDelete = (ImageButton) myView.findViewById(R.id.buttonForDelete);
buttonForDelete.setVisibility(mExpanded[position] ? VISIBLE : GONE);
buttonForRemainder = (ImageButton) myView.findViewById(R.id.buttonForRemainder);
buttonForRemainder.setVisibility(mExpanded[position] ? VISIBLE : GONE);
buttonForRemainder.setOnClickListener(new OnClickListener() {
#SuppressWarnings("static-access")
#SuppressLint("SimpleDateFormat")
public void onClick(View v) {
try {
Toast.makeText(mContext, "remainder saved..", Toast.LENGTH_SHORT).show();
} catch (Exception ex) {
Toast.makeText(mContext, "Exception in Remainder " + ex.toString(), Toast.LENGTH_SHORT).show();
}
//
}
});
buttonForCheckMark.setOnClickListener(new OnClickListener() {
public void onClick(View v){
Toast.makeText(mContext, "tapped on checkMark", Toast.LENGTH_SHORT).show();
Toast.makeText(mContext, " current Position tapped : " + position, Toast.LENGTH_SHORT).show();
if(position == 0) {
buttonForCheckMark.setBackgroundResource(R.drawable.ic_launcher);
buttonForDelete.setBackgroundResource(R.drawable.ic_navigation_cancel);
buttonForCheckMark.setClickable(false);
buttonForDelete.setClickable(true);
}
// change the status to 1 so the at the second clic , the else will be executed
// else {
// button.setBackgroundResource(R.drawable.ic_navigation_accept);
// status =0;//change the status to 0 so the at the second clic , the if will be executed
// }
// buttonForCheckMark.setBackgroundResource(R.drawable.ic_drawer);
}
});
buttonForDelete.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(mContext, "tapped on delete", Toast.LENGTH_SHORT).show();
if(position == 0) {
buttonForCheckMark.setBackgroundResource(R.drawable.ic_navigation_accept);
buttonForCheckMark.setClickable(true);
buttonForDelete.setBackgroundResource(R.drawable.ic_drawer);
buttonForDelete.setClickable(false);
// change the status to 1 so the at the second clic , the else will be executed
}
}
});
return myView;
}
public void toggle(int position) {
mExpanded[position] = !mExpanded[position];
notifyDataSetChanged();
}
/**
* Remember our context so we can use it when constructing views.
*/
private Context mContext;
/**
* Our data, part 1.
*/
private String[] mTitles =
{
"Event 1",
"Event 2",
"Event 3",
"Event 4",
"Event 5"
};
/**
* Our data, part 2.
*/
private String[] mDialogue =
{
"wuszuogwfuieffufuhuysugdueljwihadghgxdhgyhghsdgyigwuweyuqaGDHGYHGHGAdhgyhigxgxgeuyehu.",
"dgusduugyujguegytgujgdugwjhiuyg7wtqUYGYYgyijyiufufjguhgdugfhgfhgfgfhgfhghfghifgyi,dgwsdtgyfytfiuwt,",
"rtygygghtudggyjhgujtugdhhguyuaUUUUDJYUIDHUJHDIIDUJDHDUJHDIDIOUYhujtdugyhdgg",
"gjhuwjsgudggdudgjqhasdgdhgjdhushjaguhguwegagsdgygydgfgdcgycg",
"fhdgyhdfhfgdyhhwsddgyuduuufguugwugdfgugdgooduiuduiuduuduiuiuidudiiwdiou"
};
/**
* Our data, part 3.
*/
private boolean[] mExpanded =
{
false,
false,
false,
false,
false,
false,
false,
false
};
// private Integer[] mThumbIds = {
// R.drawable.remainder, R.drawable.remainder,
// R.drawable.remainder, R.drawable.remainder,
// R.drawable.remainder
//
// };
}
You cannot stop getView() method to be called automatically but you can solve your problem in alternative way.
You are inflating this layout to adapter
R.layout.activity_event_list
I am assuming your parent for this layout is Relative Layout with id as #+id/parent
Now in your getView method set the background color of row like this.
RelativeLayout parentLayout=(RelativeLayout)findViewById(R.id.parent);
parentLayout.setBackgroundColor(Color.WHITE);