Gallery item background not changed with setSelection - java

I have a Gallery with text items. I can change the selected item with the UI or programmatically with setSelection(position). However when I call this method, sometimes the item background is not changed to a selected state. I noticed that if the item called by setSelection is already drawn on the screen then its background is not updated.
Here is the code. Any help is welcome.
public class Test3 extends Activity {
private static String[] items = {"0", "1", "2", "3", "4", "5"};
public void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
LinearLayout layout = new LinearLayout (this);
layout.setOrientation (LinearLayout.VERTICAL);
setContentView (layout);
final Gallery gallery = new Gallery (this);
layout.addView (gallery);
gallery.setSpacing (0);
gallery.setAdapter (new Adapter (this));
gallery.setSelection (0);
ListView list = new ListView (this);
layout.addView (list);
list.setAdapter (new ArrayAdapter <String> (this,
android.R.layout.simple_list_item_1, items));
list.setOnItemClickListener (new OnItemClickListener () {
public void onItemClick (AdapterView <?> parent, View view, int position,
long id)
{
gallery.setSelection (position);
}
});
}
private class Adapter extends ArrayAdapter <String> {
public Adapter (Context context) {
super (context, android.R.layout.simple_gallery_item, items);
}
public View getView (int position, View convertView, final ViewGroup parent)
{
TextView view = new TextView (getContext ());
view.setText (getItem (position));
view.setBackgroundResource (R.drawable.gallery_background);
view.setGravity (Gravity.CENTER);
view.setLayoutParams (new Gallery.LayoutParams (Test3.this
.getWindowManager ().getDefaultDisplay ().getWidth () / 3,
Gallery.LayoutParams.FILL_PARENT));
return view;
}
}
}
gallery_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="#drawable/highlight_selected" />
<item android:state_checked="true" android:drawable="#drawable/highlight_selected" />
<item android:state_focused="true" android:drawable="#drawable/highlight_selected" />
<item android:state_pressed="true" android:drawable="#drawable/highlight_pressed" />
<item android:drawable="#drawable/highlight_disabled" />
</selector>

Try invalidating the gallery or notifyDataSetChanged the galleries adapter.

Related

android tabs allCaps works only for first tab

I'm trying to set my tabs text textAllCaps to false.
For some reason only firs tab has needed results, but the second is still all caps.
https://imgur.com/a/fnv2DzY
I've set tabTextAppearance to MyCustomTextAppearance and in styles two attributes are set to textAllCaps, android:textAllCaps are set to false
activity:
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/appbar"
app:tabTextAppearance="#style/MyCustomTextAppearance" />
in styles:
<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">#style/MyCustomTextAppearance</item>
</style>
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
<item name="android:textAllCaps">false</item>
</style>
in Java:
public class NewLoginActivity extends BaseActivity implements
RegisterFragment.OnFragmentInteractionListener,
LoginFragment.OnFragmentInteractionListener {
public ActivityNewLoginBinding binding;
private List<String> titles;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_new_login);
setSupportActionBar(binding.toolbar);
setToolBarTitle(getSupportActionBar(), getResources().getString(R.string.login_action_title));
if (getSupportActionBar() != null){
getSupportActionBar().setHomeButtonEnabled(false); // Disable the button
getSupportActionBar().setDisplayHomeAsUpEnabled(false); // Remove the left caret
getSupportActionBar().setDisplayShowHomeEnabled(false); // Remove the icon
}
binding.tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
binding.tabLayout.setTabMode(TabLayout.MODE_FIXED);
titles = new ArrayList<>();
titles.add(getString(R.string.login_action_title));
titles.add(getString(R.string.regi));
Bundle bundle = getIntent().getExtras();
LoginTabAdapter tabAdapter;
tabAdapter = new LoginTabAdapter(getSupportFragmentManager(), this, titles);
binding.viewPager.setAdapter(tabAdapter);
binding.viewPager.setOffscreenPageLimit(1);
binding.tabLayout.setupWithViewPager(binding.viewPager);
if (bundle != null && bundle.containsKey("signup")) {
binding.viewPager.setCurrentItem(2);
}
}

Popup context menu on ListView hold

I have a code sample got from the internet and the code goes like this
ListView lv1;
lv1 = (ListView) findViewById(R.id.custom_list);
lv1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
// print toast
}
});
Well I want to show context menu on list item click and I don't know how to do that.
You can use PopupMenu.
Create popup.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu_action1"
android:icon="#drawable/menu_action1"
android:title="#string/menu_action1" />
...
</menu>
and add this to onItemClick:
PopupMenu popup = new PopupMenu(this, v);
// this = your activity
popup.setOnMenuItemClickListener(this);
popup.inflate(R.menu.actions);
popup.show();
In addition your Activity should implements OnMenuItemClickListener so you can get menu click callback.

Get a Graph item image changing onTouch - Android

I am trying to get an individual item within a GridView to change image when a finger moves across it. I have two images, no_touch and touch. What I want is for all of the items in GridView to be set as no_touch when the activity is started, and when any one or more of the items is touched by finger just those ones change to the touch image.
All I can get so far is when one of the items is clicked it changes the background of the whole GridView (and a small toast appears). I want to be able to "glide" along each item and have only those ones change image.
My code so far:
MainActivity.java:
public class MainActivty extends Activity {
drawingView dview;
GridView grid;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity1);
final GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setVisibility(GridView.VISIBLE);
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
gridview.setBackgroundColor(Color.RED);
Toast.makeText(Activity1.this, "Position " + position,
Toast.LENGTH_SHORT).show();
}
});
}
}
ImageAdapter.java
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
public Integer[] mThumbIds = {R.drawable.images ....};
}
If anyone knows how to, even just to get an individual item changing image onClick, it would be brilliant.
Thanks in advance,
You've set the click listener on the grid. To do what you are expecting (clicking on the itens) you should set the listener on each ImageView that you have on this GridView.
Example:
imageView.setOnClickListener(new OnClickListener() {...});
If you know the size and the images that you have, a better approach would be via XML layout and drawables using the itens with the status "pressed" and default.
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/thedrawable_whenpressed">
</item>
<item android:drawable="#drawable/the_default_drawable">
</item>
</selector>

Android drawSelectorOnTop with GridView

I am developing a tabbed application in which one of the fragments, CollectionsFragment, contains a GridView with an ImageView in each slot. I would like the to use a selector to give feedback to users when the user clicks on one of the images.
I have successfully implemented the selector, however, my problem is that the selector is only drawing in the background of the image, but I would like to the selector to draw over the entire image. I have seen this problem referenced elsewhere, however, the solution selected by many, setting the drawSelectorOnTop property of the GridView, is not working for me.
The relevant fragment with the relevant adapter code:
public class CollectionsFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_collections, container, false);
// Grid view is inside the xml view inflated above
GridView gridView = (GridView)view.findViewById(R.id.gridview);
gridView.setDrawSelectorOnTop(true);
((GridView) gridView).setAdapter(new CustomGridViewAdapter(getActivity()));
return view;
}
private class CustomGridViewAdapter extends BaseAdapter {
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
View v = view;
ImageView picture;
TextView name;
if(v == null) {
v = inflater.inflate(R.layout.collections_item, viewGroup, false);
v.setTag(R.id.picture, v.findViewById(R.id.picture));
v.setTag(R.id.text, v.findViewById(R.id.text));
}
picture = (ImageView)v.getTag(R.id.picture);
name = (TextView)v.getTag(R.id.text);
Item item = (Item)getItem(i);
name.setText(item.name);
picture.setImageResource(item.drawableId);
picture.setBackgroundResource(R.drawable.selector);
return v;
}
}
}
And my selector for completeness sake:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#color/buttonhighlight"/> <!-- pressed state -->
<item android:state_focused="true"
android:drawable="#color/buttonhighlight"/> <!-- focused state -->
<item android:drawable="#android:color/transparent"/> <!-- default state -->
</selector>
Thanks for any help,
I think you are mistaken about setDrawSelectorOnTop(boolean). The selector drawable that is being referenced here is GridView's internal selector drawable.
Even in the simplest implementation of GridView, when a grid item is clicked, the blue border is drawn around it. This is because, by default, gridview's own selector is drawn behind the item. If you call setDrawSelectorOnTop(true), the selector (blue) will be drawn over the item.
But setDrawSelectorOnTop(boolean) has nothing to do with the selector you are setting in the adapter. Whether you pass true, or false, the ImageView's selector's behavior won't change.
Solution:
Instead of setting the selector on each ImageView inside the adapter, make the GridView use your selector drawable:
GridView gridView = (GridView)view.findViewById(R.id.gridview);
gridView.setDrawSelectorOnTop(true);
// Make GridView use your custom selector drawable
gridView.setSelector(getResources().getDrawable(R.drawable.selector));
Now, there's no need for:
picture.setBackgroundResource(R.drawable.selector);
Edit:
Although I don't recommend this (obvious overhead), it should work:
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
View v = view;
ImageView picture;
....
....
LayerDrawable ld = new LayerDrawable(new Drawable[]
// Drawable from item
{ getResources().getDrawable(item.drawableId),
// Selector
getResources().getDrawable(R.drawable.selector)});
// Set the LayerDrawable
picture.setImageDrawable(ld);
// Don't need this
// picture.setBackgroundResource(R.drawable.selector);
return v;
}
Try setting the xml attribute android:drawSelectorOnTop in your activity_collections.xml file.
See if placing gridView.setDrawSelectorOnTop(true); after gridView.setAdapter(); helps. Sometimes, the order matters (weird).
If all else fails, you may have to switch GridView to some other view where setDrawSelectorOnTop() is proven to work consistently.

Android ListView selected item stay highlighted

I have an XML with two ListView, one with a list of clients filled by a select query (lv_cli) and the other with the details of the client selected (lv_cli_det).
I would like to keep the client selected in the lv_cli while the lv_cli_det show the details.
XML:
<ListView
android:id="#+id/cli_lista"
android:layout_width="512dp"
android:layout_height="wrap_content"
android:fadeScrollbars="false"
>
</ListView>
<ListView
android:id="#+id/cli_lista_det"
android:layout_width="512dp"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/cli_lista"
android:fadeScrollbars="false" >
</ListView>
Java:
Cursor cursor = db.rawQuery("Select NrCl||';'||Nome From Clientes", null);
final ListView t = (ListView)findViewById(R.id.cli_lista);
ArrayAdapter<String> myarrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, listItems);
t.setAdapter(myarrayAdapter);
final ListView td = (ListView)findViewById(R.id.cli_lista_detalhe);
final ArrayAdapter<String> myarrayAdapter2 = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, listItems2);
t.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String item = ((TextView)view).getText().toString();
String[] strArray = item.split("\\;");
cli.load(strArray[0].toString());
td.setAdapter(myarrayAdapter2);
listItems2.clear();
listItems2.add("Nome: " + cli.getNome());
listItems2.add("Morada: " + cli.getMorada());
listItems2.add("Localidade: " + cli.getLoca());
listItems2.add("Código Postal: " + cli.getCp());
listItems2.add("Pais: " + cli.getPais());
listItems2.add("Nif: " + cli.getNif());
listItems2.add("Tel: " + cli.getTel());
listItems2.add("Tlm: " + cli.getTlm());
listItems2.add("Tipo Preço: " + cli.getTipoPvn());
listItems2.add("Cond. Pagamento: " + cli.getCpg());
listItems2.add("Obs: " + cli.getObs());
td.setAdapter(myarrayAdapter2);
myarrayAdapter2.notifyDataSetChanged();
}
});
I found the proper way. It's very simple.
In resource describe following:
android:choiceMode="singleChoice"
android:listSelector="#666666"
(or you may specify a resource link instead of color value)
Programmatical:
listView.setSelector(Drawable selector);
listView.setSelector(int resourceId);
listView.setChoiceMode(int mode);
mode can be one of these: AbsListView.CHOICE_MODE_SINGLE, AbsListView.CHOICE_MODE_MULTIPLE, AbsListView.CHOICE_MODE_NONE (default)
(AbsListView is the abstract ancestor for the ListView class)
P.S. manipulations with onItemClick and changing view background are bankrupt, because a view itself is a temporary object. Hence you must not to track a view.
If our list is long enough, the views associated with scrolled out items will be removed from hierarchy, and will be recreated when those items will shown again (with cached display options, such as background). So, the view we have tracked is now not an actual view of the item, and changing its background does nothing to the actual item view. As a result we have multiple items selected.
To hold the color of listview item when you press it, include the following line in your listview item layout:
android:background="#drawable/bg_key"
Then define bg_key.xml in drawable folder like this:
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="true"
android:drawable="#color/pressed_color"/>
<item
android:drawable="#color/default_color" />
</selector>
Finally, include this in your ListView onClickListener:
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,long arg3) {
view.setSelected(true);
... // Anything
}
});
This way, only one item will be color-selected at any time. You can define your color values in res/values/colors.xml with something like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="pressed_color">#4d90fe</color>
<color name="default_color">#ffffff</color>
</resources>
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
for (int j = 0; j < adapterView.getChildCount(); j++)
adapterView.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);
// change the background color of the selected element
view.setBackgroundColor(Color.LTGRAY);
});
Perhaps you might want to save the current selected element in a global variable using the index i.
Simplistic way is,if you are using listview in a xml,use this attributes on your listview,
android:choiceMode="singleChoice"
android:listSelector="#your color code"
if not using xml,by programatically
listview.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
listview.setSelector(android.R.color.holo_blue_light);
You need selector like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- State when a row is being pressed, but hasn't yet been activated (finger down) -->
<item android:drawable="#color/app_primary_color_light" android:state_pressed="true" />
<!-- Used when the view is "activated". -->
<item android:drawable="#color/app_primary_color" android:state_activated="true" />
<!-- Default, "just hangin' out" state. -->
<item android:drawable="#android:color/transparent" /></selector>
And then set android:choiceMode="singleChoice" to your ListView.
From Avinash Kumar Pankaj's example
View v;
then at oncreate method
v = new View(getActivity());
and then onlistitemclick method i wrote
public void onListItemClick(ListView listView, View view, int position,
long id) {
v.setBackgroundResource(0);
view.setBackgroundResource(R.color.green);
v = view;
}
It worked for me. Thank you.
I replaced
v = new View(getActivity());
to
v = new View(this);
and the code worked well.
It is necessary the xml files 'colors' and 'bg_key' from previous examples too, as well as ListView attribute android:background="#drawable/bg_key"
Mauro
*please be sure there is no Ripple at your root layout of list view container
add this line to your list view
android:listSelector="#drawable/background_listview"
here is the "background_listview.xml" file
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/white_background" android:state_pressed="true" />
<item android:drawable="#color/primary_color" android:state_focused="false" /></selector>
the colors that used in the background_listview.xml file :
<color name="primary_color">#cc7e00</color>
<color name="white_background">#ffffffff</color>
after these
(clicked item contain orange color until you click another item)
One way you can do this, is to Keep track of the current selected position in your activity:
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
currentPosition = position
lv_cli.notifyDataSetChanged();
}
Now, be sure you assign an ID to the parent layout (linearLayout, boxLayout, relativeLayout, .. Whatever you prefer) of your list item.
Then in your ListView you can do something Like this:
layoutBackground = (LinearLayout) convertView.findViewById(R.id.layout_background);
if (YourActivity.this.currentPosition == position) {
layoutBackground.setBackgroundColor(YourActivity.this.getResources().getColor(R.color.hilight_color));
} else{
layoutBackground.setBackgroundResource(R.drawable.list_item_drawable);
}
Basically, you just set the hilight color to the layout as a background when it equals your current selected position.
Notice how I set a drawable background resource when the item is not selected. This could be in your case different (since you posted no code). In my case, this drawable is a selector which makes sure the item is hi-lighted when pressed.
NOTE: This simple code doesn't use a view-holder, but I really
recommend using one.
Use the id instead:
This is the easiest method that can handle even if the list is long:
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Holder holder=new Holder();
View rowView;
rowView = inflater.inflate(R.layout.list_item, null);
//Handle your items.
//StringHolder.mSelectedItem is a public static variable.
if(getItemId(position)==StringHolder.mSelectedItem){
rowView.setBackgroundColor(Color.LTGRAY);
}else{
rowView.setBackgroundColor(Color.TRANSPARENT);
}
return rowView;
}
And then in your onclicklistener:
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
StringHolder.mSelectedItem = catagoryAdapter.getItemId(i-1);
catagoryAdapter.notifyDataSetChanged();
.....

Categories