Inflating same view through another xml file. Do I need unique id? - android

This is my initial layout of which the following EditText with id: assign_edit and weight_edit are part of. The name of this layout is new_class_container.
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="#+id/assign_edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:hint="#string/example_assign"
android:singleLine="true"
android:inputType="textCapWords"
android:layout_weight="1">
</EditText>
<EditText
android:id="#+id/weight_edit"
android:layout_width="fill_parent"
android:layout_weight="1"
android:layout_height="wrap_content"
android:hint="#string/example_weight"
android:layout_marginLeft="3dp"
android:gravity="center_horizontal"
android:inputType="number"
android:singleLine="true">
</EditText>
</LinearLayout>
The layout that I want to inflate is named new_class. In this layout, I copy pasted the exact same EditText's mentioned above. The following is my java file
public class DefiningClass extends Activity {
private ViewGroup mContainerView;
private EditText assignName;
private EditText assignWeight;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.new_class_container);
mContainerView = (ViewGroup) findViewById(R.id.container);
}
#Override
public boolean onCreateOptionsMenu(Menu add){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, add);
return true;
}
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case R.id.btn_save:
//INSERT INSTRUCTIONS TO SAVE
String str = assignName.getText().toString();
Toast msg = Toast.makeText(getBaseContext(),str,Toast.LENGTH_LONG);
msg.show();
break;
case R.id.btn_add:
//findViewById(android.R.id.empty).setVisibility(View.GONE);
addItem();
break;
default:
return true;
}
return super.onOptionsItemSelected(item);
}
private void addItem() {
final ViewGroup newView = (ViewGroup) LayoutInflater.from(this).inflate(
R.layout.new_class, mContainerView, false);
assignName = (EditText) newView.findViewById(R.id.assign_edit);
assignWeight = (EditText) newView.findViewById(R.id.weight_edit);
mContainerView.addView(newView, 0);
}
}
I put a Toast in my btn_save to see the work it does. When I run it, it only shows the most recent EditText. How can I make it so the toast recognizes all the edittexts that I have "inflated" and placed in it. For instance, if I had three edittexts, first said Hello, 2nd, Welcome, 3rd, Bye. The toast only shows Bye and not the other two.
What can I do for it to recognize the other two? When I save it in the future I want all the edittexts to be saved.

Use
<EditText
android:id="#+id/assign_edit"/> // missing #+
Your findViewById looks for a view with the id in the current infalted layout.
So having the same ids in different layout xml files is not a problem.
Check the topic id in the below link
http://developer.android.com/guide/topics/ui/declaring-layout.html
An ID need not be unique throughout the entire tree, but it should be unique within the part of the tree you are searching (which may often be the entire tree, so it's best to be completely unique when possible).

Related

Inflater XML Resource Type

I'am testing a new library called BottomBar of roughike, and this library help you to create a BottomBar like BottomNavigationView and this libries define your tabs in an XML resource file.
Example:
res/xml/bottombar_tabs.xml:
how can I inflate this menu? I already tried a lot of things. Obs: I can't move this file to another place.
In an old version of this library, I did this:
res/menu/bottombar_tabs
public boolean onCreateOptionaMenu(Menu menu){
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
I already tried this:
public boolean onCreateOptionalMenu(Xml xml){
getLayoutInflater().inflate(R.xml.bottombar_tabs, xml);
return true;
}
but getLayout and getMenu can't do that, and don't exist an getXml...
--Edit--
I realize that the main problem is that when I select a tab in the menu
only the Toast message appears:
if(tabId == R.id.perfil){
Toast.makeText(MainActivity.this, "Perfil", Toast.LENGTH_SHORT).show();
PerfilFragment f = new PerfilFragment();
getFragmentManager().beginTransaction().replace(R.id.bottomBar, f).commit();
}
Here is the PerfilFragment:
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState){
View v = inflater.inflate(R.layout.perfil, container, false);
return v;
}
Here the perfil layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50dp"
android:text="teste"/>
When I select the user icon in the menu the app should take me to the user page but only the Toast appears.
Here my activity_main
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottomBar"/>
<com.roughike.bottombar.BottomBar
android:id="#+id/bottomBar"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
app:bb_tabXmlResource="#xml/bottombar_tabs" />
Perfil = User.
Sorry for my english, I'm learning.

Android Fragment only uses last value for edittext after second "refresh"

I've got a fragment which dynamially adds LinearLayouts with two imagebuttons and a edittext.
The Value from the edittext is stored in a .txt File and retrieved via the function retrievecounter.
This is the Layout which gets added:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="100" >
<ImageButton
android:id="#+id/imageView1"
android:layout_width="56dp"
android:layout_height="50dp"
android:layout_weight="5"
android:src="#drawable/ic_action_photo" />
<EditText
android:id="#+id/singelfirstet1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="85"
android:ems="10" >
<requestFocus />
</EditText>
<ImageButton
android:id="#+id/buttonDelete"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="10"
android:background="#android:color/transparent"
android:contentDescription="#string/button_delete_row_description"
android:src="#drawable/testi" />
</LinearLayout>
This is my fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
ScrollView mLinearLayout = (ScrollView) inflater.inflate(
R.layout.editlistsfirst, container, false);
operations = new ArrayList<String>();
operations = retrievecounter(0);
temp = (LinearLayout) mLinearLayout.findViewById(R.id.lineartest);
LayoutInflater inflater2 = (LayoutInflater) getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < operations.size(); i++) {
View tempr = (inflater2.inflate(R.layout.list_singlefirst,
container, false));
ImageButton bt = (ImageButton) tempr
.findViewById(R.id.buttonDelete);
EditText et = (EditText) tempr.findViewById(R.id.singelfirstet1);
et.setText(operations.get(i));
String show = et.getText().toString();
Log.w("Class",show);
bt.setOnClickListener(this);
temp.addView(tempr);
}
return mLinearLayout;
}
I navigate between the fragments via an actionbar with tabs.
This is my onTabselected function:
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
ft.replace(R.id.fragment_container, fragment);
}
On the first click the values from the .txt file are displayed correctly, but after i switch to a different tab/fragment and back to this fragment only the last value of my ArrayList gets displayed.
Strange however is that the Log.w displays the correct value for the edittext both times.
Any idea what causes this?
Thanks in advance
If i call my function of the button inside the linearlayout:
temp.removeView((View) v.getParent());
for all buttons till all layouts are gone and go to another tab and back it displays the correct values, but i've got no idea why. Maybe this is helpful in finding the problem.
edit2: I Found a solution, don't know if it is practical or why it works but it does:
public void onPause(){
super.onPause();
temp.removeAllViews();
}
After i added this it works. If someone could explain why that would be much appreciated.
One of the things to consider when dealing with Views like this is that they are only 'updated' when they are first created. When you switch between your tabs, the data will not be refreshed because it was A)Not recreated [refreshed] B)Not updated by an adapter.
When you removed all views on Pause(), you emptied your view, then it is recreated from your replace() function which is similar as creating a new view. Refreshing a layout by removing and re-adding everything every time you change something can become very computationally expensive which is why people will use an adapter to control their layouts.

Button not working when restored using SharedPreferences

I have an app which inflates button views on a click of a button(Button A). The button views inflated work properly, executing the code in their onClick method.
Now to save the layout generated, I keep a count of number of times the Button A is clicked and save this value using SharedPreferences. In onCreate method I create a for loop for the number of times the Button A was clicked and re-inflate those buttons, thus generating the same layout that was on screen when the app was killed. Though now, the buttons generated in the onCreate method no longer function.
I hope I have made some sense. The problem, when the app is started again in future, it builds the layout as it was when the app was clicked, but the button views no longer function for the onCLick method.
Here's the code for reference:
MainActivity.java
public class MainActivity extends Activity {
EditText et;
String z, r;
LinearLayout ll;
SharedPreferences sp;
Button fb1;
int c=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et=(EditText) findViewById(R.id.et);
sp=getSharedPreferences("MY_PREFS", 0);
if (sp.contains("counter")) {
for (int i=1;i<=sp.getInt("counter", 1);i++) {
cr();}
}
c=sp.getInt("counter", 0);
}
public void cr() {
ll=(LinearLayout) findViewById(R.id.ll);
LayoutInflater li=getLayoutInflater();
View vw=li.inflate(R.layout.infla, null);
ll.addView(vw);
fb1=(Button) vw.findViewById(R.id.btn);
fb1.setId(c);
}
public void click(View v) {
int z=v.getId();
switch (z) {
case (R.id.button):
et=(EditText) findViewById(R.id.et);
cr();
et.setText("");
c=c+1;
break;
}
Editor e=sp.edit();
//e.putString("check", r);
e.putInt("counter", c);
//e.putInt("id", c);
e.commit();
for (int i=0; i<=c;i++){
if (z%2==0) {//Present
et.setText("Present");}
else if(z%2==1)
et.setText("Absent");
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/ll"
tools:context=".MainActivity" >
<EditText
android:id="#+id/et"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:ems="10"
android:hint="Enter something" >
<requestFocus />
</EditText>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:onClick="click"
android:text="Click" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="remove" />
</LinearLayout>
infla.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:onClick="click" />
</LinearLayout>
Edit:
You seem to have assigned redundant id's to the button during initialization.Each button would be assigned the value 'c' instead of 0 to 'c'.
Additionally It seems only logical to create click listeners on the fly as well ,since you are inflating button on the go.Try implementing the onclicklistener instead of the hardwired click() method in the xml.
i.e
public void cr() {
ll=(LinearLayout) findViewById(R.id.ll);
LayoutInflater li=getLayoutInflater();
View vw=li.inflate(R.layout.infla, null);
ll.addView(vw);
fb1=(Button) vw.findViewById(R.id.btn);
fb1.setId(c);
fb1.setOnClickListener(new View.OnClickListener(){
//Stuff you wish to do on click
});
}

Switching visibility of text field when changing number of columns gridview

I'm current having a problem designing an activity which can switch from a 'grid' to 'list' view. I'm using a GridView and to switch to the 'list', I set the maximum number of columns to 1. Now my problem is that when I switch to 'list' view, I want the image on the left along with some text on the right and not just an image in the center. All the data is taken from a custom class which is populated manually. The following images will demonstrate.
What I want:
What I have:
My Code (XML and Java) is as follows:
single_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:contentDescription="#string/content"
android:id="#+id/imageView1"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.gridview.MainActivity"
tools:ignore="MergeRootFrame" >
<GridView
android:id="#+id/gridView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="auto_fit"
android:columnWidth="128dp"
android:verticalSpacing="10dp"
>
</GridView>
</FrameLayout>
MainActivity.java
private GridView myGrid;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myGrid = (GridView) findViewById(R.id.gridView1);
myGrid.setAdapter(new myGridAdapter(this));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
GridView gv = (GridView) findViewById(R.id.gridView1);
//ImageView iv = (ImageView) findViewById(R.id.imageView1);
switch (item.getItemId()) {
case R.id.action_grid:
Toast.makeText(this, "Grid Button", Toast.LENGTH_SHORT).show();
gv.setNumColumns(GridView.AUTO_FIT);
return true;
case R.id.action_list:
Toast.makeText(this, "List Button", Toast.LENGTH_SHORT).show();
gv.setNumColumns(1);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Does anyone have any idea how I can accomplish this? I've been reading for quite some time now and have also thought of viewSwitcher and viewFlipper but don't think that they are exactly what I'm looking for. I've also juggled with the idea of creating separate activities for each layout but then also read about the drawbacks.
Thanks for your time.
The simplest option would probably be:
Add a TextView in single_item.xml, and position it to the right of the image.
Pass the current state of the GridView (i.e. the mode it's in) to your custom adapter.
In the Adapter's getView(), depending on this state:
Call setVisibility() on the TextView, with either VISIBLE or GONE.
Update the ImageView's layoutParams, to align it to the center or right of its parent.
This does not require any duplication.
Example code:
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
convertView = LayoutInflater.from(mContext)inflate(...);
}
TextView tv = convertView.findViewById(R.id.textView1);
ImageView imageView = convertView.findViewById(R.id.imageView1);
// Show/hide text according to ListView mode.
tv.setVisibility(mMode == SHOW_TEXT ? View.VISIBLE : View.GONE);
// also update imageView.getLayoutParams() according to mMode.

Trouble with EditText inside a (Sherlock)Fragment

Hey Everyone,
I am having some trouble with my edit texts in my Fragment. I get a NUllPointerException on the EditText.getText().toString(). I know there are a few similar threads on this but I have had not luck fixing my problem. I have tried putting the (EditText) getView().findViewById(...) both the in the onCreateView() and in the onActivityCreated() and still I get the NullPointerException.
I have attached (what I think is) the relevant code. Let me know if you need to see any more of the code.
The NullPointerException is in the Intent createShareIntent() method. I have commented the line where I get the exception.
public class EditNoteFragment extends SherlockFragment {
Long mCurrentPosition;
EditText title;
EditText body;
// in a fragment class this does not do anything.
// it is mostly here to register for the menu and context menu. that is all
// seems silly :/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (savedInstanceState != null) {
mCurrentPosition = savedInstanceState.getLong("RowId");
}
View view = inflater.inflate(R.layout.edit_note, container, false);
title = (EditText) view.findViewById(R.id.title);
//title.setText("");
body = (EditText) view.findViewById(R.id.body);
// body.setText("");
return view;
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem menuShare = menu.findItem(R.id.menu_share);
ShareActionProvider shareAction = (ShareActionProvider)
menuShare.getActionProvider();
shareAction.setShareIntent(createShareIntent());
}
protected Intent createShareIntent() {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, title.getText().toString()); // From logcat I can see the NullPointerException here
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, body.getText().toString());
return shareIntent;
}
As requested the relevant xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:focusable="true"
android:focusableInTouchMode="true"
android:hint="#string/titlehint"
android:inputType="textCapSentences"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textStyle="bold" />
<EditText
android:id="#+id/body"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_margin="5dp"
android:layout_weight="1"
android:fadeScrollbars="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="top"
android:hint="#string/noteshint"
android:inputType="textMultiLine"
android:scrollbars="vertical" />
Any help would be appreciated.
Cheers.
Simply do this.
if(title!=null){
final String text = title.getText();
if (!TextUtils.isEmpty(text)) {
// creates the intent and fires it...
} else {
// shows an error message that the text is required.
}
}
Is is bound to work
The method of EditText.getText() retrieves an object of kind Editable only if the edit text contains any text field inside (Editable is the product of the text filled by the user in the box with graphical properties).
You should do the following:
final String text = title.getText() != null ? title.getText().toString() : null;
if (!TextUtils.isEmpty(text)) {
// creates the intent and fires it...
} else {
// shows an error message that the text is required.
}
Hope it helps.. :)

Categories

Resources