i'm trying to make a spinner with just arrow but without title, which looks like google maps using to get user's origin or destination for directions
and after you click on the arrow(triangle), start a new map as background.
i have searched for quite a time, found most relate topic are about remove that arrow with a new background , or how to set the prompt/hint/text before selecting any items in the list.so far i got no luck
is that really a spinner? or just a button+popwindow ?or it's related to the adapter?
thank you very much ...
by
LayoutInflater inflater = getLayoutInflater();
View empty = inflater.inflate(R.layout.empty, parent, false);
return empty;
in getView of class that extends ArrayAdapter, now there is
what ever which item is selected,but how to remove the underline and the space it takes, change background?
another solution is as #codeMagic said, with a image button and on click method. and by the way i found
<EditText
android:id="#+id/date"
style="#android:style/Widget.Holo.Spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
as mentioned in here
and look like
a little weird.
Related
I have an app that's getting information from an API request and then displaying a list of devices. After several hours of combing through documentation, I cannot figure out how to format the View that is created from the ArrayAdapter. Essentially, if the device has an error, I want to display a red circle to the right of the button and display a green button if there is no error.
deviceList is the name of a ListView that I am trying to display my list of buttons inside of. deviceNames is an array of strings that contains the names of the devices.
The TextViews that are created are also clickable, which is what the onItemClickListener is handling. This section works, but I wanted to leave it in because I do need the buttons to start an activity that displays device-specific information.
Ideally I would like to essentially create a template that I can just change the values of the text and the color of the indicator for
Below is my code:
// List of device names
val listView: ListView = findViewById(R.id.deviceList)
val arrayAdapter1: ArrayAdapter<*>
arrayAdapter1 = ArrayAdapter(
this#Homepage,
R.layout.device_button,
deviceNames
)
listView.setAdapter(arrayAdapter1)
listView.onItemClickListener =
AdapterView.OnItemClickListener { parent, view, position, id ->
val pos = position
println(pos)
val device = jsonArray.getJSONObject(pos)
val ID = device.get("id") as String
println(ID)
goToDeviceDetail(ID)
}
Below is the XML file for device_button. I tried to add formatting here and essentially create a template for a button that would allow me to change the text and the color of the indicator, but it got mad that it wasn't just a TextView.
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:gravity="center_vertical"
android:textColor="#25383C"
/>
Below is the button that I would like for it to look like. I'm likely going to just make the background a solid color rather than the image that is in the below picture:
I would say the biggest problem is your using a simple API for a more complex problem. It is entirely possible do it with a ListView and ArrayAdapter. But I would highly recommend looking into RecyclerView/RecyclerView.Adapter
The way it works out is...
RecyclerView.Adapter binds your list of data ie Devices to the individual RecyclerView.ViewHolder
The ViewHolder would inflate your xml layout that contains the button. You then have access to all View contained in that layout easily.
You then can put listeners on the button.
The Adapter then can be setup to receive new data, when received it can rebind the data that has changed.
Say the user clicks one of the device buttons it does a task. When it gets back it will say hey Adapter I have a new List for you.(The list now contains the "fixed" device).
ViewModel(contains observable data)->Fragment/Activity(Observers the data)->Adapter(Receives the data)->ViewHolder(Displays the data)->Activity("Fixes the data")->ViewModel->...loops
Here is a very good example.
https://medium.com/#atifmukhtar/recycler-view-with-mvvm-livedata-a1fd062d2280
If you really want to keep using the ListView and ArrayAdapter you are receiving the clicked view here.
OnItemClickListener {
/*Parent of the view*/ parent,
/*The view clicked*/ view,
/*position of data*/position,
/*id of the view clicked*/ id
->{
view.findById(R.id.text_view);
//onClick
}
}
With that you know what has been clicked so you know what has to be changed later when you get back from your other Activity.
I want to create an expandable list view except in this case, when a list item is clicked, i do not want to just want to show another a list of strings but rather I want it to show a layout with text fields and drop downs etc.
So far, I have parentlayout with textview to show the titles, childlayout with fields in it. Just not sure how to show the child layout on list item click. Any help is greatly appreciated!
HashMap<String, List<String>> would be used if I wanted to show a list of strings so in my case, what do I use? HashMap<String, ?> what goes here?
Looks like you are looking for something like BaseExpandableListAdapter. You can customize both the group and child views with whatever you want.You just have to implement some of the methods.For example getGroupView and getChildView will return any View. You can inflate the view in this method and set it up too.
Here are two articles for reference:
http://www.javacodegeeks.com/2013/06/android-expandablelistview-with-custom-adapter-baseexpandablelistadapter.html
http://theopentutorials.com/tutorials/android/listview/android-expandable-list-view-example/
What I ended up doing, which was much easier and more effective is I created a linear layout with all the fields I needed and added some textviews to serve as section titles. Then I declared it like so
in onCreate
textview= (LinearLayout)findViewById(R.id.textviewid);
textview.setVisibility(View.GONE);
Then wrote a method called toggle
public void toggle_basicInfo(View v){
if(textview.isShown()){
textview.setVisibility(View.GONE);
}
else {
textview.setVisibility(View.VISIBLE);
}
}
my xml looked like
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Basic Info"
android:clickable="true"
android:onClick="toggle_basicInfo"
android:textSize="20sp"
android:paddingTop="8dp"
android:id="#+id/text"
android:layout_above="#+id/linearLayout"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textColor="#ff3a65ff" />
when I click my textview, it will hide/show whatever you define to hide. for example you can hide a LinearLayout etc. Also by doing it this way, state entries for text fields are maintained when hidden and shown.
I would like to make Android ListView non clickable for sometime, until my AysncTask finished.
So I Used
lv.setClickable(false);
But its not working. ListView still takes clicks. Need help.
What has worked for me is setting two attributes in the XML for my list items. I set clickable="false" and focusable="true". So each of my list items is inflating an XML file similar to this one:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="true" >
<!-- Children here -->
</LinearLayout>
I'm not sure exactly why this works, although this is my guess:
Using just the clickable attribute doesn't work because although the LinearLayout isn't clickable, the children inside it still are. Then the children get the click event but don't use it and forward it up to the LinearLayout.
By making the LinearLayout focusable, it will now take the click event, and then drop it because it isn't clickable.
Hope this helps. If anyone knows for sure why this approach works, please chime in.
Try this instead:
lv.setEnabled(false);
EDIT: ok sorry my fault.
I think the problem is that its not the ListView you are clicking but the View representing each item in your ListView. So try this:
View itemView = lv.findViewTraversal(id_of_your_view);
itemView.setClickable(false);
I hope this works.
did you try setFocusable / setEnabled methods ?
You can in your onItemClick method :
if(!mWorking){
mWorking = true;
//do the job...
}
You can try to implement a SimpleOnGestureDetector and override the onSingleTapConfirmed method. There is a lot of tuts on google.
I hope this will help you
I am using a Gallery with an ImageAdapter to load it with ImageViews that pull images out of my resources. My problem is that the convertView that gets passed to the getView() method in my adapter is always null. This means that a new ImageView is created each and every time getView() is called. This leads to horrible preformance because the GC is constantly running to wipe away all of these created and no longer used ImageView's.
This is apparently a known bug: Gallery's view cache is broken; never converts views..
My two preferred solutions are either 1. handle a cache of views in the adapter itself and take care of all the logic required to re-use them properly.
or 2. include a my own copy of the Gallery widget and try to fix it so it properly returns recycled views.
I've started implementing option one but am quickly realizing I don't exactly know how to make all of the logic behind that operation. I am begining to think that option two might be easier.
I've found the code for the Gallery widget here: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/widget/Gallery.java
I don't fully understand it, but I can see that it is calling
child = mAdapter.getView(position, null, this);
on line 745. My (shot in the dark) guess that this is the root of the problem.
Does anyone have experience with this bug. Or can anyone point me in the right direction for figuring out how the recycler situation works so that I can tweak this widget to work correctly? Or even suggest some alternate option that I may be overlooking.
EDIT: The best solution that I ever found was an implementation called EcoGallery. The only place I can find reference to it online anymore is here. To get it working you have to put each chunk from there in the correct place within your project.
No experience with that bug particularly, but I have done custom caching before with a 3rd party view pager (before the support lib).
It's really not too difficult honestly. In my case, I knew there would be, at most, one item on the screen. But I also wanted the item to the left and right to be preloaded (these were webviews pulling data off the net). So I have a simple array of 3 views.
[V1, V2, V3]
Now the only thing you need to do is correlate a position in your adapter to a position in your cache. There's a variety of ways you could tackle this. When I first spiked it out, I just made whatever my current view was to be V2 and the rotated the items of the array around when flipping the pager. So flipping to the next view would alter my array
[V2, V3, V1]
Was simple to keep up with. Or you could just do the math and calculate a position to a relative position of the cache.
Another approach is to create a last in, first out queue. Recycle views by pushing them into the queue, and when you need a view, just pop one from it.
I do not have experience with Gallery widget, but I'am using a lot ListView with images. According to your problem, and link to Google issue, they still haven't fix this problem.
So, there is solutio with nice library (and examples within it), which solve cache/ajax problems, and much more.
Link to library
or, more concrete, link to image examples
If you download their examples, you will find how they implemented gallery with Gallery widget, using their AQuery utility class in
com.androidquery.test.image.ImageLoadingGalleryActivity class.
Snippet from code:
final List<Photo> entries;// here only to show what enteries are...
listAq = new AQuery(this); //define as Action class member, here only to show what it is
ArrayAdapter<Photo> aa = new ArrayAdapter<Photo>(this, R.layout.gallery_item, entries){
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = getLayoutInflater().inflate(R.layout.gallery_item, parent, false);
}
Photo photo = getItem(position);
AQuery aq = listAq.recycle(convertView);
aq.id(R.id.name).text(photo.title);
String tbUrl = photo.tb;
if(!aq.shouldDelay(position, convertView, parent, tbUrl)){
aq.id(R.id.tb).image(tbUrl);
aq.id(R.id.text).text(photo.title).gone();
}else{
aq.id(R.id.tb).clear();
aq.id(R.id.text).text(photo.title).visible();
}
return convertView;
}
};
aq.id(R.id.gallery).adapter(aa);
Where Photo is just POJO object (fetched from remote):
class Photo {
String tb;
String url;
String title;
String author;
}
R.id.gallery refers to
<Gallery
android:id="#+id/gallery"
android:layout_width="fill_parent"
android:layout_height="200dip" />
And R.layout.gallery_item refers to:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dip"
android:layout_height="75dip" >
<ProgressBar
android:id="#+id/progress"
android:layout_width="15dip"
android:layout_height="15dip"
android:layout_centerInParent="true" />
<ImageView
android:id="#+id/tb"
style="#style/GalleryItem"
android:layout_width="100dip"
android:layout_height="75dip" />
<TextView
android:id="#+id/text"
android:layout_width="100dip"
android:layout_height="75dip"
android:gravity="center"
android:maxLines="4"
android:padding="15dip"
android:text="Dummy TextDummy TextDummy TextDummy TextDummy Text"
android:textColor="#FFFFFFFF"
android:textSize="8sp" />
</RelativeLayout>
Hope you'll find this library useful in solving your problem.
I've gotten around this by using a custom cache as dskinner suggests.
I pre-calculate (screenwidth/minwidth of item) the max # of items that can be show in the gallery on the screen at one time and add a few more (the gallery will need extra to show items on the left and right as you scroll thru it). I create an array of this size - the views get created as requested and placed in the cache. Use position % cachesize to figure out which cached view to return when getView is called.
How yo set listview background like this.
I want to appear when the number of record 0
There is special method in ListView - setEmptyView(). You can find examples of using it here or here.
Upd: second link is unavailable now. Here is quote from article:
When you set a ListView’s “empty view” programmatically, you can end up scratching your head as to why your empty view actually doesn’t appear when the list is empty.
If this happens, then what you forgot is that you must manually add your empty view to your view hierarchy, cos ListView won’t do it for you. Although it’s obvious when you think about it, the documentation doesn’t mention this detail, and Googling shows at least one person had the problem.
Here’s the code with the lines that it’s all too easy to forget at numbers 4 and 5…
TextView emptyView = new TextView(context);
emptyView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
emptyView.setText(“This appears when the list is empty”);
emptyView.setVisibility(View.GONE);
((ViewGroup)list.getParent()).addView(emptyView);
list.setEmptyView(emptyView);
Just set a background image at the parent layout and then set the color of the ListView to fully transparent:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
style="#style/Main" android:background="#drawable/background">
<ListView android:cacheColorHint="#00000000" .../>
</LinearLayout>
Read the documentation of the ListActiviy. You can define a view which will automatically shown when the list is empty and has not items. The view for the empty list got to have the id android:id/empty.
So no need to play around with the background.
You can set a drawable as background with ListView.setBackgroundDrawable()
You need to check before passing array/arraylist into adapter ,if the length of array/arraylist is 0 then add this image to your main layout.