Dialog when user hold a link - java

I have seen a lot of Android browsers which shows a dialog box when user holds a link or an image.
I am new to android and I have created a simple browser, and now I want to make this possible, so when user hold a link I have to show dialog like this
http://the.url.com
--------------------- Open Copy link address Select Text
Any tutorial or a sample code would be helpful.

You can use ContextMenu for that purpose.
//Constants for context menu options
public static final int MENU_OPEN= 1;
public static final int MENU_COPY= 2;
public static final int MENU_SELECT= 3;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
...
...
// Especify that your veiw have a context menu attached
registerForContextMenu(your view);
}
// here you create the conext menu
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
menu.add(Menu.NONE, MENU_OPEN, Menu.NONE, "Open");
menu.add(Menu.NONE, MENU_COPY, Menu.NONE, "Copy link address");
menu.add(Menu.NONE, MENU_SELECT, Menu.NONE, "Select Text");
}
// This is executed when the user select an option
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case MENU_OPEN:
return true;
case MENU_COPY:
return true;
case MENU_SELECT:
return true;
default:
return super.onContextItemSelected(item);
}
}

Related

Android WebView - Text Selection Listener in 2018

I will create an app that user will be enter the website url to my app. Then I am showing this page in my app using WebView.
As you know, when user clicks the any text in the context a little bit long, android cursor will appear then we can select text as many as we want.
After selection, we will see that "COPY, SHARE, SELECT ALL" etc..
My question is that when user selects text, I want to show them different options. Let's say "MyCOPY, SendTwitter, SendMessage".
How can i do that?
What I did so far?
I am just creating bar at the top of the app. But I don't want this.
Here is the code:
private WebView view;
private final String TAG = MainActivity.class.getSimpleName();
private ActionMode actionMode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.view = findViewById(R.id.webView);
view.loadUrl("https://stackoverflow.com/questions/28385768/android-how-to-check-for-successful-load-of-url-when-using-webview-loadurl");
view.setWebViewClient(new MyWebViewClient());
Log.d(TAG, view.getUrl());
view.setOnLongClickListener((v) -> {
if (actionMode != null)
return false;
actionMode = startSupportActionMode(actionCallBack);
return true;
});
}
Where startSupportActionMode(actionCallBack) is
private ActionMode.Callback actionCallBack = new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
actionMode.getMenuInflater().inflate(R.menu.custommenu, menu);
actionMode.setTitle("Choose");
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.example_item_1:
Toast.makeText(MainActivity.this, "Option 1 selected", Toast.LENGTH_SHORT).show();
actionMode.finish();
return true;
case R.id.example_item_2 :
Toast.makeText(MainActivity.this, "Option 2 selected", Toast.LENGTH_SHORT).show();
actionMode.finish();
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(ActionMode actionMode) {
actionMode = null;
}
};
You can implement the ActionMode.Callback interface to create your own menu upon selection.
An action mode's lifecycle is as follows:
onCreateActionMode(ActionMode, Menu) once on initial creation
onPrepareActionMode(ActionMode, Menu) after creation and any time the
ActionMode is invalidated
onActionItemClicked(ActionMode, MenuItem)
any time a contextual action button is clicked
onDestroyActionMode(ActionMode) when the action mode is closed
just make sure that your text views allow for text selection (android:textIsSelectable="true")
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
// Called when the action mode is created; startActionMode() was called
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
return true;
}
// Called each time the action mode is shown. Always called after onCreateActionMode, but
// may be called multiple times if the mode is invalidated.
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false; // Return false if nothing is done
}
// Called when the user selects a contextual menu item
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_share:
shareCurrentItem();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
// Called when the user exits the action mode
#Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
};
then call startActionMode() to enable the contextual action mode when appropriate (source), such as inside a setOnLongClickListener

Global value becomes null in method

I have created a private member of the whole class called Member curMbr;
The activity (rather the fragment, since this is in a frament class) has a listview
with some contributions from members.
I also have a context menu on that list. When clicking on a contribution, I want a (customized) dialog box to show details about the member. (Member ID is part of the contribution objet. )
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
Log.d("FRGCOTIZ02", "create ctxt menu");
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
String[] menuItems = getResources().getStringArray(R.array.ar_menu_ctxt_participant);
// Get selected member
Contribution curCotis = (Contribution) (((ListView)v).getItemAtPosition(info.position));
Participant p = new Participant(helper.getDBItem(DBHelper.TABLE_PARTICIPANT,
DBHelper.COL_ID, curCotis.getParticipant()));
curMbr = new Member(helper.getDBItem(DBHelper.TABLE_MEMBER, DBHelper.COL_ID, p.getMember()));
for (int i = 0; i < menuItems.length; i++) {
menu.add(Menu.NONE, i, i, menuItems[i]);
}
Log.d("FRGCOTIZ01", curMbr.getId_());
}
#Override
public boolean onContextItemSelected(MenuItem item) {
return ( applyContextMenuSelection(item) || super.onContextItemSelected(item) );
}
private boolean applyContextMenuSelection(MenuItem item) {
switch (item.getItemId()) {
case 0: // Summary
final Dialog dlg = new Dialog(this.getContext());
final String sessID;
try {
sessID = KUtil.DATE_FORMAT.format(curSess.getDate());
dlg.setContentView(R.layout.alert_show_charges);
Button btnOK = dlg.findViewById(R.id.btn_alertOK);
btnOK.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
setupAlertDialogCharges(dlg, sessID, curMbr.getId_());
}
});
Button btnCancel = dlg.findViewById(R.id.btn_alertCancel);
btnCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dlg.dismiss();
}
});
dlg.show();
} catch (Exception e){
Log.d("FRAGMENT Contribution", e.getMessage());
}
break;
case 1: // Collect
break;
case 2: // Cancel
break;
default:
break;
}
return true;
}
In method onCreateContextMenu, I can get the member and display his ID.
But in method applyContextMenuSelection, there is an exception, saying the meber is null!
Funny enough there is another variable that I am using in that method, and it works fine. Difference is, that variable has been set at creation of the fragment.
How do I solve this?
I have been studying the code for a while and the only thing I could figure was that the issue is somehow linked to the use of contextmenu. It seems to me that variables are set back to their original when the menu action is supposed to be executed. Again, I am not too sure about that.
So, the only solution I found so far was to keep that vale in a "higher" context:
When I can still read the value,
getActivity().getIntent().putExtra(HomeActivity.ID_ENTRY, curMbr.getId_());
When I want to use it,
final String mbrID = getActivity().getIntent().getStringExtra(HomeActivity.ID_ENTRY);

Implementing search in listview

I'm working on a PDF reader. I've created a list view which will hold all the PDF files you're having in your mobile.
Now when I'm implementing a search on this listview using EditText field, the problem is, it is not able to search files properly, like for example, I've 5 files named as
sample.pdf, resume-sample.pdf, resume sample.pdf, resume.pdf, sampleresume.pdf.
Now if I search:
"sample" I'll get the following result: sample.pdf and resume sample.pdf
"resume" I'll get the following result: resume sample.pdf and resume.pdf
As we can see this is not the exact result of what we expect, it should have listed all the files having either "sample" or "resume" in it.
It is able to search only when the 2 words are separated having space between them, it is not able to read the second word if there is no space or _ or - between the 2 words.
Please let me know if it is possible to implement a perfect search for my problem, thank you.
This is the code for my EditText listener:
search.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence a, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence a, int start, int before, int count) {
pdf.arradapter.getFilter().filter(a.toString());
}
#Override
public void afterTextChanged(Editable a) {
}
});
You can use Search View instead. Just create a menu.xml file which contain this
<item
android:id="#+id/search_icon"
android:icon="#android:drawable/ic_menu_search"
android:title="#string/search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always|collapseActionView" />
inflate the menu inside your activity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.your_menu_name, menu);
return true;
}
implement SearchView.OnQueryTextListener() to your activity
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id. search_icon:
SearchView searchView = (SearchView) item.getActionView();
searchView.setInputType(InputType.TYPE_CLASS_TEXT);
searchView.setQueryHint("PLACEHOLDER");
searchView.setOnQueryTextListener(this)
return true;
default:
return super.onOptionsItemSelected(item);
}
}
you can manipulate your list inside onQueryTextChange(String newText) method
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
newText = newText.toLowerCase();
List<Item> newTransaction = new ArrayList<>();
for (Item item : getData()) {
String name = item.getItem_name().toLowerCase();
if (name.contains(newText))
newTransaction.add(item);
}
adapter.setFilters(newTransaction);
return true;
}
}
Adapter is your custom adapter for your Adapter List View, getData return list, and inside the setFilters method
public void setFilters(List<Item> filters) {
items = new ArrayList<>();
items.addAll(filters);
notifyDataSetChanged();
}
I hope that helps. You can check this tutorial if you are confused here

I need to hide/show a particular item from popup menu on given condition

I tried this solution, but it doesn't work as I expected. Here is my code, and this is what i have tried.
PopupMenu popup = new PopupMenu(TableActivity.this, view);
popup.setOnMenuItemClickListener(TableActivity.this);
menu = popup.getMenu();
popup.inflate(R.menu.popup_shift);
popup.show();
popup.setOnMenuItemClickListener(this);
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_merge:
if(tableDbList.get(positionShift).getMergeTableId()== 0) {
//this is the condition to show/hide popup menuitem
popup.getMenu().findItem(R.id.menu_merge).setVisible(false);
}else {
checkPinCode.checkPinCodemethod(TableActivity.this, "mergeCancel");
}
}
return true;
}
You are trying to change visibility on MenuItem click . It will work but popupMenu will dismiss just after click . So it does not make any sense.
If your requirement is to show items on some condition you should set visibility before show(). Below is a simple example .
private void showPopup() {
final PopupMenu popup = new PopupMenu(MainActivity.this, view);
popup.getMenuInflater().inflate(R.menu.popup_shift, popup.getMenu());
if(someCondition){
popup.getMenu().findItem(R.id.menu_merge).setVisible(false);
}
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(MainActivity.this, "You Clicked : " + item.getTitle(), Toast.LENGTH_SHORT).show();
return true;
}
});
popup.show();
}

Getting the selected item's position in Android popup menu class

I want to store some data into every item in a popup menu. All of the items are inflated programatically in a for loop based on results returned from a feed.
In the following example, I use a HashMap storedOption to store each item's data with the loop indices as keys. But I need to find a way to get the position of the selected item in onMenuItemClick so that I can retrieve the data from storedOption. Can anyone tell me how to do that? Besides the following attempt, I have also tried item.getOrder() but it always returns 0 regardless of how many items it has in the menu.
public DynamicPopUpMenu{
private Map<String,FeatureList> storedOption = new HashMap();
public void main(final Context context,List<FeatureList> featureList){
int count = 0;
PopupMenu menu = new PopupMenu(context, featureList);
for(FeatureList f:featureList) {
MenuItem item = menu.getMenu().add(f.key);
storedOption.put(count, f);
count++;
}
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position = info.position;
new ShowToast(context,Integer.toString(position)); // show position in a toast
return true;
}
});
menu.show();
}
}
You could use featureList.key as the key of your storeOption and them use item.getItemId(); to get the value from storeOption.
Like this:
public DynamicPopUpMenu{
private Map<String,FeatureList> storedOption = new HashMap();
public static void main(final Context context,List<FeatureList> featureList){
int count = 0;
PopupMenu menu = new PopupMenu(context, featureList);
for(FeatureList f:featureList) {
MenuItem item = menu.getMenu().add(f.key);
storedOption.put(f.key, f);
count++;
}
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int id = item.getItemId();
FeatureList mFeatureList = (FeatureList)storedOption(id)
new ShowToast(context,Integer.toString(value)); // show position in a toast
return true;
}
});
menu.show();
}
}

Categories