public void onClick(View arg0) {
final Dialog dialog = new Dialog(Hero.this);
ListView list = new ListView(Hero.this);
final ArrayList<Spell> spells = new ArrayList<Spell>();
for (int i = 0; i < MainActivity.charSpells.size(); i++){
if (MainActivity.charSpells.get(i).getType() == Spell.SPELL){
spells.add(MainActivity.charSpells.get(i));
}
}
list.setAdapter(new ArrayAdapter<Spell>(Hero.this, R.layout.row, spells));
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(list);
dialog.setCanceledOnTouchOutside(true);
dialog.show();
list.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
spell1.setText(spells.get(arg2).getSc());
MainActivity.spells[0] = spells.get(arg2);
dialog.dismiss();
}
});
}
I made this Dialog which contain a ListView, but the items can ony be selected when you click on the text and not, like it should be, on the whole row.
Can anyone find my mistake?
EDIT:
OK, solved it, I used a builder to make the dialog:
https://stackoverflow.com/a/6157258/2468567
If that's happening, I'm assuming your TextView resource must be set to wrap_content for both height/width, which would mean the only touchable area is where the actual text is.
Try changing their values in the XML to fill_parent (or a fixed size or whatever you're doing). Then adjust the android:gravity to adjust where the text is placed within the View.
Recap:
android:layout_width="fill_parent"
android:layout_height="fill_parent
android:gravity="center"
Try to make the width bigger then the screen on the TextView
list.xml
android:layout_width="1000dp"
Related
I'm facing a problem. Not sure what to call it, or what causes it
I'm learning Android SQLite and to train started making a simple note app.
The problem is I have a custom dialog for category select, before opening the dialog everything is fine in the EditText field, but after opening, and closing it the text starts writing over, like creating multiple layers of the same text and the text cursor leaves a line after every symbol. (See "bug demo" GIF of the problem)
Has anyone else seen something like this? What could be causing this, the dialog?
Edit:
So this is the code that takes action when clicking on the star to open the dialog
starred.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(CreateNoteActivity.this);
View mView = getLayoutInflater().inflate(R.layout.dialog_category_select, null);
ListView categoryList = mView.findViewById(R.id.category_list);
Button cancelSelect = mView.findViewById(R.id.cancelSelect);
final CategoryListAdapter adapter = new CategoryListAdapter(CreateNoteActivity.this);
categoryList.setAdapter(adapter);
//get the data and append to a list
Cursor data = myDB.getCategories();
while(data.moveToNext()){
Category thisNote = new Category(data.getInt(0), data.getString(1), data.getString(2));
adapter.add(thisNote);
}
categoryList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, final int i, long l) {
final Category selectedCategory = (Category) adapterView.getItemAtPosition(i);
int duration = Toast.LENGTH_SHORT;
String s = "Category celected: "+selectedCategory.getCategoryName();
Toast toast = Toast.makeText(context, s, duration);
toast.show();
}
});
builder.setView(mView);
final AlertDialog selectCategory = builder.create();
selectCategory.getWindow().setBackgroundDrawable(new ColorDrawable(getResources().getColor(android.R.color.transparent)));
selectCategory.show();
View decorView = getWindow().getDecorView();
decorView.setBackgroundResource(android.R.color.transparent);
int width = (int)(getResources().getDisplayMetrics().widthPixels*0.80);
int height = (int)(getResources().getDisplayMetrics().heightPixels*0.80);
selectCategory.getWindow().setLayout(width, height);
cancelSelect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectCategory.dismiss();
}
});
}
});
This answer might help you
Write this after the dialog close
ediText = findViewById(R.id.edit_text);
editText.setSelection(editText.getText().length);
Basically using the above logic, the cursor won't be pointed at the first character of the editText on the dialog close
Noticed that I was trying to set a transparent background to display my custom dialog bcg two times.
So what fixed the problem was removing two lines
*View decorView = getWindow().getDecorView();
decorView.setBackgroundResource(android.R.color.transparent);*
Not sure why it was causing this. Should check what is getDecorView() method. Used it cause found it as a solution to show the custom background.
This line works as well
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(getResources().getColor(android.R.color.transparent)));
Guess this was a case of rubber duck debugging - just had to tell someone about the problem to fix it. Thanks everyone.
Try this code when you dismiss or close the dialog,
edittext.setSelection(editText.getText().toString().trim().length);
I'm using this code
ListView lv = getListView();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView idno = (TextView) view.findViewById(R.id.idno);
TextView fullname = (TextView) view.findViewById(R.id.fullname);
TextView remark = (TextView) view.findViewById(R.id.remark);
new DisplayStudent().execute("Update", idno.getText().toString());
if(remark.getText().toString().equals("absent")) {
if(isStudentLate) {
view.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.colorLate));
fullname.setTextColor(Color.WHITE);
remark.setText("late");
}
else {
view.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPresent));
fullname.setTextColor(Color.WHITE);
remark.setText("present");
}
}
else if(remark.getText().toString().equals("present") || remark.getText().toString().equals("late")) {
view.setBackgroundColor(Color.WHITE);
fullname.setTextColor(Color.BLACK);
remark.setText("absent");
}
}
});
((BaseAdapter)getListView().getAdapter()).notifyDataSetChanged();
Everytime I tap on an item, the background color of the item I tapped is supposed to change. Why does it not change? I tried removing the ((BaseAdapter)getListView().getAdapter()).notifyDataSetChanged(); it does change but when I scroll down and scroll up again it goes back to its original background color.
For example. One Item's background color is colored white. When I tap that item, it changed to green. That's perfect. But when I scroll down and scroll up again, the item that I tapped changed back to white. How do I fix this?
Try setting this in your ListView tag:
android:cacheColorHint="#00000000"
And also try this:
android:background="color code here"
I would like to implement dialog such this one
User hits the button "Icon", this dialog opens, user chooses appropriate icon by pressing on it, then dialog closes and returns to me id of this icon.
How could I do it?
Thanks.
You want to create an alertDialog with a custom grid in it. In my answer I assume that OP wanted to know how to create such a dialog in general. Therefore I am using a normal style. If you want to use a dark style, create a custom styling and use it in your AlertDialog.Builder:
AlertDialog.Builder builder = new AlertDialog.Builder(context, <YourCustomStyle>);
Result:
Create the layout for a single entry. Since OP is only showing icons, I only use an ImageView. If the icon should for example have text under it, you simply could create a TextView below it and fill it with your text.
view_icon_chooser_entry.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/image_choose_icon_entry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:contentDescription="#null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
Create an adapter that can deal with the data and create the layout. In my example I am extending from a BaseAdapter since this is quite easy to do. A little bit more modern would be to use a RecyclerView and create your own custom adapter for it.
AlertDialogImageAdapter.java:
public class AlertDialogImageAdapter extends BaseAdapter {
private LayoutInflater layoutInflater;
AlertDialogImageAdapter(Context context) {
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return iconList.length;
}
#Override
public Object getItem(int position) {
return iconList[position];
}
#Override
public long getItemId(int position) {
return position;
}
#SuppressLint("InflateParams")
#NonNull
public View getView(int position, View convertView, #NonNull ViewGroup parent) {
AlertDialogViewHolder alertDialogViewHolder;
if (convertView == null) {
// This is an alertDialog, therefore it has no root
convertView = layoutInflater.inflate(R.layout.view_icon_chooser_entry, null);
DisplayMetrics metrics = convertView.getResources().getDisplayMetrics();
int screenWidth = metrics.widthPixels;
convertView.setLayoutParams(new GridView.LayoutParams(screenWidth / 6, screenWidth / 6));
alertDialogViewHolder = new AlertDialogViewHolder();
alertDialogViewHolder.icon = convertView.findViewById(R.id.image_choose_icon_entry);
convertView.setTag(alertDialogViewHolder);
} else {
alertDialogViewHolder = (AlertDialogViewHolder) convertView.getTag();
}
alertDialogViewHolder.icon.setAdjustViewBounds(true);
alertDialogViewHolder.icon.setScaleType(ImageView.ScaleType.CENTER_CROP);
alertDialogViewHolder.icon.setPadding(8, 8, 8, 8);
alertDialogViewHolder.icon.setImageResource(iconList[position]);
return convertView;
}
// This is your source for your icons, fill it with your own
private Integer[] iconList = {
android.R.drawable.ic_media_play, android.R.drawable.ic_media_pause,
android.R.drawable.ic_delete, android.R.drawable.ic_btn_speak_now,
android.R.drawable.ic_media_previous, android.R.drawable.ic_media_next,
android.R.drawable.ic_menu_my_calendar, android.R.drawable.ic_menu_agenda,
android.R.drawable.ic_media_play, android.R.drawable.ic_media_pause,
android.R.drawable.ic_delete, android.R.drawable.ic_btn_speak_now,
android.R.drawable.ic_media_previous, android.R.drawable.ic_media_next,
android.R.drawable.ic_menu_my_calendar, android.R.drawable.ic_menu_agenda,
android.R.drawable.ic_media_play, android.R.drawable.ic_media_pause,
android.R.drawable.ic_delete, android.R.drawable.ic_btn_speak_now,
android.R.drawable.ic_media_previous, android.R.drawable.ic_media_next,
android.R.drawable.ic_menu_my_calendar, android.R.drawable.ic_menu_agenda
};
private class AlertDialogViewHolder {
ImageView icon;
}
}
Then, place a method to create a new AlertDialog with your custom AlertDialogImageAdapterand use a grid for the layout. You can change how many columns you have with setNumColumns(4).
Put this method where you want to show the alert dialog and simply call it:
private void showAlertDialog(Context context) {
GridView gridView = new GridView(context);
gridView.setAdapter(new AlertDialogImageAdapter(context));
gridView.setNumColumns(4);
gridView.setGravity(Gravity.CENTER);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO: Implement
Toast.makeText(view.getContext(), "Clicked position is: " + position, Toast.LENGTH_LONG).show();
}
});
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setView(gridView);
builder.setTitle(R.string.title_chose_icon);
builder.show();
}
I will suggest you to "imitate" the dialog and not using the android one.
For that, you can create a second layout with the dark grey background and all your clickable icons inside. When you will call the dialog, set the dimming to the main layout and put the one with the icons on the top.
I am using this in my app. I will provide you some code in 10min.
Have a look at the fragments section in the API Demo app. There are some dialogs you can use
I've created an array of 5 clickable textviews using a loop, have set their parameters (size, colour, background image, to be clickable etc) and have set an onClickListener and the array is called "myArrayofTVs". Their ids have been set using the loop int (i). I have another predefined array that hold text string, and other textviews are present on the layout. Later on in the onClick method, and as all the buttons/clickable textviews do something very similar, I'd like to be able to do something like:
#Override
public void onClick(View v) {
if(v == myArrayofTVs[i]) { //using 'i' here doesn't seem to work
tv1.setText(myArray2[i]);
tv2.setText(myArray2[i+1];}
etc
etc}
I've tried various differnt ways such as using switch case statements (don't really want to use these as there will be a lot of repeated code and I'll have to add a new case statement each time I want to add new textview/buttons in the future). Is there anyway of using one statement that will handle all the buttons/clickable textviews based on the variable id given or will I have to use a separate case/tag/id statement for each one?
Many thanks in advance!
Add the views to your ViewGroup and use getChildAt(int index) and getChildCount() to create a loop. You can loop all children/views in the viewgroup and you could check with
if(child instanceof TextView)
if they are of the correct type. Then you could cast the views back to a TextView/Button/View and do the thing you want to do.
But it sounds like you want a list of something. So i would suggest using a ListView with a adapter behind it.
I really think you should use the id provided by Android instead of trying to compare objects. The reason your code wouldn't work, if it had a sufficient for loop around it, is somewhat mysterious, but I would try to parallel the switch statements you see in examples as much as possible by comparing ID's and not objects.
for( int i = 0; i < myArrayofTvs.length; i++ )
if(v.getId() == myArrayofTVs[i].getId()) {
tv1.setText(myArray2[i]);
tv2.setText(myArray2[i+1];
}
}
Also obviously you'll want to avoid an array out of bounds error in that second inner statement.
What I did was programmatically inflate my custom layout and used an onClickListener on that button from the custom layout inflated. Then to interact with a specific item I got the parent view of the view being clicked eg. your button and then used that view to change attributes of the view. This is a snippet of my code. The onClick of the alertDialog is where I go about changing values of the newly inflated view.
// if an edit button of numbers row is clicked that number will be edited
if (view.getId() == R.id.NumberRowEditButton)
{
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Contact edit");
alert.setMessage("Edit Number");
// Set an EditText view to get user input
final EditText input = new EditText(this);
input.setSingleLine();
alert.setView(input);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int whichButton)
{
// get input
Editable value = input.getText();
if(value.length() > 4){
View tempView = (View) view.getParent();
TextView tempTV = (TextView) tempView.findViewById(R.id.numberRowTextView);
String number = tempTV.getText().toString();
tempTV.setText(value.toString());
}
else
{
// ...warn user to make number longer
final Toast msgs = Toast.makeText(ContactEdit.this, "Number must be over 4 digits.", Toast.LENGTH_SHORT);
msgs.setGravity(Gravity.CENTER, msgs.getXOffset() / 2, msgs.getYOffset() / 2);
msgs.show();
}
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int whichButton)
{
// cancel the dialog
dialog.cancel();
}
});
alert.show();
}
Hopefully this might help you.
I am trying to implement a drop down list when a button is clicked.
So, I have a text view and a button in a navigation bar(nav.xml) and a corresponding list view. This navigation bar is included in another page( products.xml)
when the button is clicked i get the list view right below the button(which is what i want to acheive) but its my moving all the contents on the current page downwards, even the text view which is placed in nav bar moved downwards.
I am totally new to Android, any sample examples or a way how to achieve it
???
Sounds like you need a Spinner. It's the equivalent of a drop down list for Android. You can find an example here.
So, for our need we need to use ListPopupWindow.
The link to official description:
http://developer.android.com/reference/android/widget/ListPopupWindow.html
Let's dive in the code:
we have our own method:
public void downloadBtnSelected(View anchor) {
final ListPopupWindow lpw = new ListPopupWindow(this);
String[] data = { ".png", ".pdf", ".jpg", ".jpeg" };
PopupAdapter pa = new PopupAdapter(data, this);
lpw.setAdapter(pa);
//setting up an anchor view
lpw.setAnchorView(anchor);
//Setting measure specifications. I'v used this mesure specs to display my
//ListView as wide as my anchor view is
lpw.setHeight(android.widget.LinearLayout.LayoutParams.WRAP_CONTENT);
lpw.setWidth(anchor.getRight() - anchor.getLeft());
// Background is needed. You can use your own drawable or make a 9patch.
// I'v used a custom btn drawable. looks nice.
lpw.setBackgroundDrawable(this.getResources().getDrawable(
android.R.drawable.btn_default));
// Offset between anchor view and popupWindow
lpw.setVerticalOffset(3);
lpw.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
/// Our action.....
lpw.dismiss();
}
});
lpw.show();
}
and the button with an onClickListener to call this method:
Button btn = new Button(this);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
downloadBtnSelected(v);
}
});
we pass the View v argument as our anchor, in order to let our PopupWindow to know where to display itself. It will be displayed in the bottom-left corner of our anchor view if there is enough room below. If not- it will displa