I have an instance of an AlertDialog that I am using as a file selection dialog. It includes a hierarchical browsing function - if a directory is selected from the list, it should show the list of files in that directory. It also includes a 'up level' button, that returns to the previous folder. I need a way to update the contents of the AlertDialog object's built-in ListView while the dialog is displaying without reloading the dialog object from its builder. I am aware that Adapters exist, but I need a way to load data from a defined instance variable, not an external XML resource. I am overriding the onResume method to avoid dialog closure on button press, and this is where I need to run the list update.
This is the code I have now for the selection button's OnClick listener inside the onResume method.
alertDialog.getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
if(position >= 0)
{
String[] list = getCurrentFileList();
if(list[position].equals(NO_ITEMS_TEXT)){
return;
}
// If the selected file is a directory, recursively update the file list and redisplay.
if(getCurrentFileRefList()[position].isDirectory()){
src = getCurrentFileRefList()[position];
parseFileList();
//todo update ListView from loaded file list
}else { // If the selected item is a file, give the value to the handler and dismiss the dialog.
handler.handleEvent(DialogActionEventHandler.ResultID.SUBMITTED, getCurrentFileRefList()[position]);
alertDialog.dismiss();
}
}
}
});
The parseFileList(); method is used to get the current list of files from the selected source file.
Any help would be appreciated!
You should notify the UI to update the list by calling notifyDatasetChanged
https://developer.android.com/reference/android/widget/BaseAdapter.html#notifyDataSetChanged()
Once you update the data in the adapter, you must call Adapter.notifyDatasetChanged.
I eventually solved the issue with a workaround - here's how.
Since the notifyDatasetChanged() method did not push updates to the dialog correctly without creating an entire adapter class for the initial creation stage - something which I considered far too time-consuming and inefficient for my purposes - I worked around the issue by relaunching the dialog every time an update was needed, and tracked the current directory's position in the master tree relative to the source directory by using an ArrayList with a pointer that updated every time the user switched folders. This process also required making the onCreate() method relaunch-aware, and enabling the onResume() method to be called manually. Once these were done, the resultant section of code looked like this:
alertDialog.getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(position >= 0)
{
String[] list = getCurrentFileList();
if(list[position].equals(NO_ITEMS_TEXT)){
return;
}
// If the selected file is a directory, recursively update the file list and redisplay.
if(getCurrentFileRefList()[position].isDirectory()){
src = getCurrentFileRefList()[position];
hierarchyID ++;
onCreateDialog(null);
alertDialog.dismiss();
}else { // If the selected item is a file, give the value to the handler and dismiss the dialog.
handler.handleEvent(DialogActionEventHandler.ResultID.SUBMITTED, getCurrentFileRefList()[position]);
alertDialog.dismiss();
}
}
}
});
This discards the old dialog, updates the hierarchy tree tracking array and associated pointer, and relaunches the dialog with the new path. It is significantly more complex than I hoped, but it works well. I hope someone finds this useful!
Related
I am working on stripe-terminal-android-app, to connect to BBPOS 2X Reader device,
wanted to click-item from list,(recyclerView).
I am trying to do:
when list of devices appears(readers), I am checking if readers.size()==1, then click first-device from list,else show recyclerView();
I have very less experience in Android(coming from JS, PY), :)
After going through debugger to understand flow of program-running, I used F8 key, or stepOver the functions one by one,
and where value is assigned to convert in displayble-format in adapter as here.
public ReaderAdapter(#NotNull DiscoveryViewModel viewModel) {
super();
this.viewModel = viewModel;
if (viewModel.readers.getValue() == null) {
readers = new ArrayList<>();
} else {
readers = viewModel.readers.getValue();
if(readers.size() == 1){
Log.e(TAG, "readers.size() is 1 "+ readers.size());
}
}
}
then in ReaderHolder-file, values are bind() as
void bind(#NotNull Reader reader) {
binding.setItem(reader);
binding.setHandler(clickListener);
binding.executePendingBindings();
}
}
I tried assigining button and manually clicking when only-one device appears, by clicing on reader[0], can't do that by findViewById inside Adapter file, to call onClick() method manually,
I tired another StackOverflow's answer but didn't understood, from here.
Main fragment is discovery-fragment,
how can I click first-device by checking readers.size()==1, then click onClick()?
my final-goal is to automate, whole stripe-terminal-payment process on android.
extra-info:
I am fetching data from python-odoo server, then using url, will open app through browser, (done this part), then device will be selected automatically as everytime-no any devices will be present except one,
so will automatically select that from recyclerView, then proceed.
I have asked for help in detailed way on GitHub-issues, and started learning Android's concepts for this app(by customizing stripe's demo app, which works great, but I wanted to avoid manually clicking/selection of devices).
I have an application that helps users organize prescriptions. I have one listview that shows medications and I use an EditText to allow the user to filter the list. The problem I'm having is that the CursorLoader is replaced each time the orientation changes.
From what I understand, the LoaderManager.initLoader() function should be called in onActivityCreated(). In my particular case, I don't have a fragment so I put the initLoader() call inside onPostCreate():
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
getSupportLoaderManager().initLoader(MEDICATION_LOADER, null, this);
}
And here is the filter I'm using:
// Set text filter
mMedication.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mMedicationAdapter.getFilter().filter(s);
}
});
I removed the empty beforeTextChanged and afterTextChanged methods to shorten this.
So, what appears to be happening (from using the debugger) is that each time I change the device orientation, initLoader() is called again and the entire list of medications are displayed, not just the filtered ones. Is there a way to implement onSaveInstanceState() to store the current filtered state of the adapter?
Or am I using the text filter wrong? Should I pass the charSequence as a Bundle argument to the loader, or create another loader that handles the text as an argument?
A solution is you can keep the current activity when orientation changes, Just set the Activity to handle config changes in AndroidManifest.xml:
Android config changes
e.g.
<activity
android:name="com.test.MyActivity"
android:configChanges="screenSize|orientation"/>
If your edittext was inflated through a layout file and it has an id; the framework should be automatically save its text.
You could try checking right before you attach your textwatcher, if the edittext has any text inside, then filter your list and then attach your textwatcher.
i am working on an app to develop my knowledge so far i have created a calendar app which user can make appointment when clicking on a date. i then have a delete button which opens all the appointments created in a fresh activity, there i have: a list view which displays all appointments a textview which displays the selected appointment (selected by the user to delete) and a button remove. the remove button removes all the items from the sqlite but i can only see this working when the application is restarted i know i am missing something else in my code.. how do i clear the listview at the same time any help would be much appreciated
my code:
delete all method
public void deleteAll() {
db.delete(TABLE_NAME, null, null);
}
button code:
public void onClick(View v) {
switch(v.getId()){
case R.id.removeBtn:
dm.deleteAll();
break;
}
thank you
}
Maybe not the most elegant, but I don't build my UI in onCreate(). Instead, in onCreate(), I call another method initializeUI(), and that is where I build my user interface. Then, anytime I do something that should be reflected in the interface (update the database or whatever), I just need to call my method initializeUI() again.
Edit: Also look into notifyDataSetChanged() for your adapter as exampled here
First check if your database is writable (getWritableDatabase)
Then check that your "TABLE_NAME" is in fact the table name.
Then you could try to use execSQL("delete from " + TABLE_NAME);
if that does not work, you could try to close the db.
finally try putting it in a transaction
beginTransaction();
.. delete..
endTransaction();
If you are actually changing the data from the Adapter used in the ListView, you could use requery() method on the cursor used to populate the Adapter. This should reflect your changes!
Hi am working on an android application. And am using a listview in some of my activities.
The problem is all of my listviews displayed are much longer so that the user needs to scroll the whole list to go for the last item.
Am trying to implement a pagination for this, like at first say only 20 items need to displayed on the listview. And at the end of my listview i need a titlebar which have next & previous buttons and on clicking on next button the listview will load the next records from 21st to 40 and so on.
Am using java rest webservice to load the listview.
Can anyone give me a good suggestion for solving my problem.?
Solution 1:
You can load all the data at once if its not TOO MUCH, store it locally & then you can navigate in that locally stored data. Define some variables like StartPoint & EndPoint & get the desired data from that stored data. Increment decrement the values of StartPoint & EndPoint by using the PreviouButton & NextButton.
Solution 2:
Get only the desired data from your data source for example 10 records each time when a Navigation button is clicked.
I suggest than you load list data in a custom Adapter class that extends BaseAdapter class. Like #oriolpons suggested, you should add a footer view, and when you click on button next call some method that is fetching next for example 20 rows, and then add them in your adapter object and call notifyDataSetChanged().
For example
private OnClickListener mListener = new OnClickListener() {
public void onClick(View v) {
ArrayList<YourObject> al = getSomeData(int startRow, int endRow);
MyCustomAdapter adapter = new MyCustomAdapter();
for(YourObject a : al)
adapter.add(a);
getListView.setAdapter(adapter);
notifyDataSetChanged();
}
};
Hope this helps.
The easiest solution is to add a footer view to the listview. And on the item click listener you can see if it is the last position (load more items), or not
//add the footer before adding the adapter, else the footer will not load!
View footerView = ((LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listfooter, null, false);
this.getListView().addFooterView(footerView);
#Tijo . Refer this site http://www.androidhive.info/2012/03/android-listview-with-load-more-button/. You can have a button which would call the execute method of Async task and that will load the remaining list for you.
I'm creating an application similar to the link given here, where it shows three images transition from one state to another when click.
1) Stage 1: When a series of listview of video files are stored in a video directory. How do i create this particular view into the ListView?
2) Stage 2: When a video file is being click it does not immediately play the video instead it shows a dialog box showing the detail of the file.
3) Stage 3: The user could either Exit, Select Play video or show roadmap details...
Could someone help me i'm kinna new in android/java here, i'm totally lost on how to start creating the above views like how do i populate the Listview with existing video files found in my video directory?
You realize that your basically asking someone to make the application for you? In any case, I shall try to give you some help to get started.
Stage 1: Do you know how to create a ListView? Here's an example:
listView = (ListView) findViewById(R.id.list_view);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, elements); //elements is a List<String>
listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//What to do when an item is clicked
}
});
You can customize the look of the list items by creating a XML-file containing a single TextView and then use that when creating the ArrayAdapter (like R.layout.list_item).
If you want a completely custom View, like in the app in the link, you can create your own adapter and then implementing the View getView(int position, View convertView, ViewGroup parent) function, where you return the View you want to be displayed.
Example:
View row = convertView;
if (row == null) {
LayoutInflater mInflater = LayoutInflater.from(getContext());
row = mInflater.inflate(R.layout.bookings_list_item, parent, false);
}
return row;
You can create the elements list by counting the files in the video directory. I don't really know how to do this, but it shouldn't be too hard. Perhaps someone else can provide you with an answer if you don't find out yourself.
Stage 2: Implement this in the OnItemClickListener in the example above by showing a dialog.
Stage 3: Implement what the Dialog will do when it's buttons are pressed. Exit: dismiss popup. Play video: Launch an intent to a video player. I'm not sure about how to show roadmap details, but you can always use Google Maps in your app (there's a sample here).
Now, I hope you can get something useful from this. I hope I have provided you with enough details to be able to get started with researching and a little coding. :)