I've built a View which displays data driven by the respective Java Activity class. The data comes from the first element of a Collection.
On a button click from the view (onClick), I want to display the second element of the Collection in the view (replacing the first element).
What is the best way to achieve this? Here is what I was thinking:
onClick invokes a method in the Activity class which modifies the state of existing view elements?
onClick reloads the Activity and the state of the Collection still exists to be able to present?
Some other way?
Not sure if 1 will work as the Model isn't bound to the view elements? Some kind of refresh will be needed.
2 sounds overkill if you just want to keep the view structure the same but modify the state of elements.
Thanks in advance.
Use ViewSwitcher
<ViewSwitcher
android:id="#+id/viewswitcher"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="firstClick" />
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
android:onClick="secondClick"
</ViewSwitcher>
In java code
firstClick()
{
viewswitcher.setDisplayedChild(1);
}
secondClick()
{
//whatever you need
}
Here when you click on a the first view(It can be a button), the second view can be made visible by replacing the first one. Use it as per your convenience.
I was over thinking this. All I had to do was update the state of the view objects in the java layer and the view would automatically 'paint' the changes.
Related
Please Read My Question Carefully
I am learning Activity LifeCycle. I only have one EditText and a TextView in my XML layout With certain id. When I rotate the screen, nothing seems to change because Rotation doesn't affect EditText. But when I remove the id of EditText in XML and rotated the screen, The Rotation Starts affecting and the text in the editText removed due to rotation. I am confused about the relation of EditText with its Id.
I tried to explain the problem below in columns:
Explanation of below Column names
Having Id: Does EditText has id?
Rotation : Phone has Rotated or not
EditText : What happen to EditText After Rotation.
.
Having Id----------------Rotation---------------EditText
Yes Rotated Does not change
No Rotated Yes, Text Removed from editText
MainActivity.java is empty and main_activity.xml code is below:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Enter here"
android:inputType="textPersonName"
android:textSize="26sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.371" />
<TextView
android:id="#+id/textView2"
android:layout_width="85dp"
android:layout_height="25dp"
android:layout_marginTop="88dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Sorry for using bad English and High-resolution pictures as I have no other ways. Best Regards
One of the most important aspects in Android programming is to handle the configuration changes and most common of them is orientation changes. Although it is not recommended to handle configuration changes yourself, due to the hidden complexity of handling the configuration changes, there are cases where we might need to handle manually.
If you need to save the state, the common approach is to implement onSaveInstanceState to store & restore the values which are passed as Bundle.
Coming back to your question:
Relation of EditText with its Id in Android Studio?
When it comes to saving state of View Android OS automatically calls the View.onSaveInstanceState method on each of the views in your view hierarchy as long as you call through to the super method in onSaveInstanceState. In order to restore the data, it uses android:id attribute key for that particular View’s state.So for your case, when you don't provide the id for EditText, the View's state won't be stored due to missing key.
Hope this clarifies the relationship of id to EditText
When you rotate screen on android all activities and fragments in your application are destroyed and then recreated. Android does this so that your application can reload resources based on the new configuration.
When the system destroys the activity (e.g. when the screen rotates) then although the actual Activity instance is gone, the system remembers that it existed. The system creates a new instance of that activity using a set of saved data that describes the state of the activity when it was destroyed.
when your assign an id to a view it seems that android keeps track of that view. Hence it remembers it's state.
Okay when you rotate the device this is considered as a configuration change, so the system recreates the activity and data is lost.
One way to avoid this is go to the manifest and for your specific activity add this
android:configChanges="orientation|screenSize"
here:
<activity
android:name=".YourActivityName"
android:configChanges="orientation|screenSize"
....
...
This makes the system ignore the rotation of device.
In manifest of your app, add this line to activity tag:
android:configChanges="keyboardHidden|orientation|screenSize"
The reason for this is due to Android basically destroying the activity and creating it again every time you rotate the device. This is mainly to allow for different layouts based on portrait/landscape mode.
When you use id for your component, data will be assigned to its id, but when it hasn't id, it will be recreated and data will be disappeared after rotation.
See these questions and read their good answers, I don't copy and paste them:
1- TextView's text disappearing when device rotated
2- Handle screen rotation without losing data - Android
EditText is a focused view, so in PhoneWindow, it's state will be saved automatically in saveHierarchyState() method. Only EditText with id is going to save text.
Okay, the relation of one specific EditText item to its id is: "one to one" or "one to N". One EditText item in one layout.xml has one id, if you've configured it in the layout.xml. If you've defined more than one layout.xml's and the very same EditText item (having the same id) in more than one layout.xml's, then EditText has a "one to N" relation.
I have a layout with some clickable views in it.
I have implemented swipe gesture as per this.
This is working great if you swipe in an empty area, but it does not work if you start swiping inside one of the views inside the layout.
How can this be avoided? Adding onSwipeListener to ever single view in the activity seems insane. Is there a better way?
my working solution to this problem is using an invisible layer above the view with children as following:
<RelativeLayout
android:id="#+id/contentLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/linearLayout"
android:layout_alignStart="#+id/linearLayout"
android:layout_alignParentTop="true">
...
</RelativeLayout>
<View
android:id="#+id/gesture_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/linearLayout"
android:layout_alignStart="#+id/linearLayout"
android:layout_alignParentTop="true"
android:focusable="true"
android:focusableInTouchMode="true" />
where contentLayout contains multiple children including some buttons.
Second step is catching touch events on this gesture_view and proxying them to both contentLayout and my GestureDetector code (similar to the one you linked on the question) as following:
gesture_view.setOnTouchListener { _, event ->
contentLayout.dispatchTouchEvent(event)
gestureListener.onTouch(event)
true
}
Note, you need to be careful about how you deliver the events to the view behind gesture_view. Simply contentLayout#onTouch will not work. It has to be contentLayout.dispatchTouchEvent
Set android:clickable=false in your child views. This will prevent them from intercepting the touch events from the parent.
In my app, users can either take a picture or record a video. The file is then saved and its path is passed through an intent to the next activity, which displays it for editing.
My question is, how can I easily use the same view for either a video or an image?
I tried dynamically adding a view at runtime when I know what the file type is, but it turned out to be too hard to configure, not to mention the issues that VideoViews have with being rotated.
Edit:
I forgot to mention that using the same view would be preferable, since I'm not actually going to do anything to the contents that's specific to each kind of view.
Add both the ImageView and VideoView in your layout. Then set the visibility to GONE or VISIBLE for the one you want.
You can create two child views, one for the image and one for the video. And depending on the type of your view you can hide/show your child views.
You can also use FrameLayout for this
By using frame layout / Relative layout you can place a view on top of another view. After creating the views like i mention and using the visibility Gone & Visible you can manage to handle it..
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/ImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/my_drawable"
android:scaleType="fitCenter"
android:visibility="gone"/>
<VideoView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:padding="5dp"
android:id="#+id/VideoView"
android:visibility="gone"/>
</FrameLayout>
Then based on your usage you can control it dynamically like below
// register the views
ImageView mImageView= (ImageView)findViewById(R.id.ImageView);
VideoView mVideoView= (VideoView)findViewById(R.id.VideoView);
// check your conditions like show video view r image view here
if(VideoView)
{
mVideoView.setVisibility(View.VISIBLE);
mImageView.setVisibility(View.GONE);
}
else if(ImageView)
{
mImageView.setVisibility(View.VISIBLE);
mVideoView.setVisibility(View.GONE);
}
Hope it will work for you :)
I want to create a ListView and a few other text boxes for filtering the list.
Is there a way to make it happen using one activity (i.e at the same page)?
One more question:
May I modify a ListView directly without creating a ListActivity? and how do I make the ListView in my ListActivity visible? (how do I link it with the xml?).
Yes. ListActivity seems to cause a lot of confusion for people, when all it is, is a regular activity with a ListView as the content, some helper methods, and that's it.
To add your own, create a new layout file and add all the widgets you need like you would any other layout file. Example:
<LinearLayout xmlns:android="http://schemas.android.com/res/apk/android"
android:weightSum="1.0"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/whatever"
android:layout_weight="0" />
<ListView
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1" />
</LinearLayout>
You certainly can create a layout which contains both a ListView and other controls! Make your Activity have a layout which contains both your ListView and your other controls.
<RelativeLayout>
<ListView android:id="#+id/listy"/>
<Button android:id="#+id/buttony"
android:layout_below="#id/listy"/>
</RelativeLayout>
In your Activity, you'll still need to hook up your data adapter to the ListView and so forth.
Yes, you can have ListView together with some other required views with in the same Activity. The way I would do this is to define an Activity and add ListView (with width and height set to fill_parent) and add a SlidingDrawer which contains all the options required to alter ListView. With this approach, your ListView will take up all the space on screen and offering user to interact freely. However, on the other hand, SlidingDrawer will give give extra space for all the list altering views/options.
I am wondering what's the difference between #+id/android:list and #+id/list. I know the last one which is a regular id assignment but the first looks different. What makes it special?
Where I saw it:
I was studying on ListView, ListAdapter and things like that and the author define the ListView in layout xml file as below :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
android:id="#+id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<TextView
android:id="#+id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="#string/main_no_items"/>
</LinearLayout>
and also let me mention #+id/android:empty id as well.
And he also extends ListActivity class.
Here is the source of the article.
And also what's in my mind as questions are :
Should we extend ListActivity? Maybe I want an Activity which also contains other Views.
We use #+id/android:list just because we extend ListActivity or we can use the same convention if we extend Activity?
Thanks.
Resource IDs in Android are specific to a package (which is good, or else you'd have lots of conflicts if your app is dealing with several packages at the same time).
#+id/list will create a resource ID in your app (=your package) with the name "list" and give it a unique ID. In code, that would be R.id.list.
#android:id/list will use the ID "list" from the package android (which, in code, would be android.R.id.list.
EDIT: Need to add the corrections David Hedlund pointed out: The proper reference would be #android:id/list. Also, + indicates you're defining a new ID - you obviously don't need that when you're referencing something that was defined in the Android API.
I think the example code you posted has a typo, so it should be #android:id/list (without the +). From the ListActivity javadoc:
your own view MUST contain a ListView object with the id "#android:id/list"
#android:id/list is specific to ListActivity, so you do not need it if you are adding a ListView into any other kind of Activity. You should extend ListActivity if you want the user to do more than view the list. For example, you can override ListActivity.onListItemClick to respond to clicks on an item in the list.
Similarly, #id/android:empty (again, without the +), is a special case for ListActivity. This allows you to specify an alternative view that should be displayed when your list is empty. That View will not be displayed when the list is populated.
in android,
In XML: #[package:]layout/filename
like
android:id="#+id/android:list"
This is the standard way to refer to a list view when refering to listFragment or listActivity
so filename is android:list is a reference to ListView.
navigate to res/values/ids.xml
you will find <item type="id" name="list" />
ListView is a view group that displays a list of scrollable items. The list items are automatically inserted to the list using an Adapter that pulls content from a source such as an array or database query and converts each item result into a view that's placed into the list.