I am having trouble trying to figure out how to convert my current tab setup to one that uses views and not seperate activities... I have issues with calling my search function and I think it is due to the way I have created my tabs.
My main launcher activity is public class Menu extends TabActivity which creates the tabs
intent = new Intent().setClass(this, TabGroup1.class);
// Initialize a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("codes").setIndicator("All Codes",res.getDrawable(R.drawable.ic_tab_codes))
.setContent(intent);
tabHost.addTab(spec);
`TabGroup1' does the following for each tab
public class TabGroup1 extends TabGroupActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startChildActivity("Category", new Intent(this,Category.class));
}
}
Which then calls the ListActivity which shows the content from there when an item is clicked another intent is created which then starts a new activity which allows me to have the tabs on each level as the user goes down the lists.
This is done with the following code
public void onListItemClick(ListView parent, View view, int position, long id) {
Intent intent = new Intent(getParent(), SubCategory.class);
Cursor cursor = (Cursor) adapter.getItem(position);
intent.putExtra("CATEGORY", cursor.getString(cursor.getColumnIndex("_id")));
/*startActivity(intent);*/
TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startChildActivity("SubCategory", intent);
}
TabGroupActivity is a class which I found from a tutorial that allows you to have multiple activities under the same tab layout.
What I am struggling is with converting what I have to using views and using setContent to change the views.
I have found this example but it doesn't provide enough detail for me to go on.
Also found this one as well...
Can someone please provide me the run down on what I need to change and also how do I setContent using my listactivities...
Thanks in advance
A couple things... setContent defines the content, it doesn't cause the switching of tabs. If you want to force a change to a certain tab you use TabHost.setCurrentTab(tabid);, otherwise it defaults to the first tab, then whatever the user chooses.
An example from one of my own projects (This project actually has four tabs, but I've cut out some to try and keep this to the point). There are several ways to do it, but I found the easiest was to create a method to populate each tab, that way I could refresh a tab as needed by calling the appropriate method for whichever tab I needed (all of the java below is contained in the TabActivity).
setupdetailmain.xml
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="5dp" >
<TextView
android:id="#+id/setupheader"
android:layout_width="fill_parent"
android:layout_height="20dp"
android:textSize="15dp" />
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:gravity="bottom" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp" >
<!-- General Info Tab -->
<LinearLayout
android:id="#+id/note_tab"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
<!-- Tool Tab -->
<LinearLayout
android:id="#+id/offset_tab"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ListView
android:id="#+id/list2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:drawSelectorOnTop="false" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
tab setup code (extends TabActivity)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setupdetailmain);
// ***************************************************************
// Set up the tabs in the tabhost
// ***************************************************************
tabHost = getTabHost();
TabHost.TabSpec spec;
spec = tabHost.newTabSpec("Offsets").setIndicator("Offsets")
.setContent(R.id.offset_tab);
tabHost.addTab(spec);
spec = tabHost.newTabSpec("Notes").setIndicator("Notes")
.setContent(R.id.note_tab);
tabHost.addTab(spec);
populateTabs(StartTab);
}
tab populate methods
// ***************************************************************
// Fill the Notes tab
// ***************************************************************
private void notestab() {
notes = (LinearLayout) findViewById(R.id.note_tab);
notestxt = new TextView(this);
notestxt.setText(SETUPINFO_NOTES);
notestxt.setTextSize(15);
notes.addView(notestxt);
}
// ***************************************************************
// Fill the Offset tab
// ***************************************************************
private void offsettab() {
wpccount = 0;
for (int i = 0; i < 20; i++) {
if (wpcdesc[i] != null) {
wpcdisplayhold[wpccount] = wpcid[i] + " - " + wpcdesc[i];
wpcidhold[wpccount] = wpcid[i];
wpcdeschold[wpccount] = wpcdesc[i];
wpccount++;
}
}
wpcdisplay = new String[wpccount];
for (int i = 0; i < wpccount; i++) {
wpcdisplay[i] = wpcdisplayhold[i];
}
mWPCView = (ListView) findViewById(R.id.list2);
mWPCView.setAdapter(new ColorizingListAdapter(SetupDisplay.this,
wpcdisplay, "Offset"));
registerForContextMenu(mWPCView);
}
This uses a custom adapter, but hopefully it gets across the idea of how to set up your lists in a tab view without doing a new activity.
Related
The basic view hierarchy is this:
secondActivity
linearLayout(LinearLayout)
constLayout(ConstraintLayout)
textbox(TextView)
image(ImageView)
image2
image3
...
The textbox TextView has visibility GONE, and goal is to make it VISIBLE on clicking other visible siblings, change some colors and text, and when clicked again it must be invisible again and reverse all changes.
Cant understand whatever it is that am missing. I have checked many older projects in which I did the same thing and cant find any visible differences as to why this code is not working now.
secondActivity.java
public class secondActivity extends Activity {
public boolean isTextBoxHidden;
public ConstraintLayout constLayout;
public TextView textbox;
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
constLayout = findViewById(R.id.constLayout);
textbox = findViewById(R.id.textbox);
isTextBoxHidden = false;
// SETTING UP LISTENER
View.OnClickListener clickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!isTextBoxHidden) {
constLayout.setBackgroundColor(Color.BLACK); //setting color on previously
v.setBackgroundColor(Color.BLACK); //setting color on visible view
textbox.setText("whatever");
textbox.setVisibility(View.VISIBLE); //was gone
isTextBoxHidden = true;
}
else {
textbox.setVisibility(View.GONE); //hide again
constLayout.setBackgroundColor(Color.WHITE);
v.setBackgroundColor(Color.WHITE);
isTextBoxHidden = false;
}
}
};
// INSERTING LISTENERS into all children
for(int i=0; i<constLayout.getChildCount(); i++) {
constLayout.getChildAt(i).setOnClickListener(clickListener);
}
}
}
activity_second.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".secondActivity">
<android.support.constraint.ConstraintLayout
android:id="#+id/constLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white">
<TextView
android:id="#+id/textbox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="example"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<ImageButton
android:id="#+id/image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="#drawable/example"
android:clickable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<!--few more clones of the first imageButton-->
</android.support.constraint.ConstraintLayout>
</LinearLayout>
I can't see where you're setting textbox reference, so maybe that's a clue.
Edit:
Did compiled that example you have provided and everything works correctly, but i assume that [...] gone again for good meant you probably want this to be one shot action so instead of boolean just use Boolean and compare it to null.
Edit:
On the second thought you can just remove isTextBoxHidden = false; in else branch
Firstly, I'm extremely unsure on the majority of Android coding, this is only my second day doing it, so please excuse any mistakes I make in my explanations!
I've got a database via SQLite and currently display my data via a listView. Currently, it works fine displaying the data and I can scroll through and click on it no issues. However, I'd like to place my data within the "Scrolling Activity" template you can find in Android Studio. From Googling around, I understand somewhat that you can't place a listView in a nestedScrollView, which is what the activity uses.
I am unsure, however, how to display my data from the database without using a listView. Could somebody please help me either convert the listView into something compatible, or explain a way to combine them (Hacky methods are fine for now!)
I've displayed all of the necessary code below.
MainActivity.java:
mydb = new DBHelper(this);
ArrayList array_list = mydb.getAllCotacts();
ArrayAdapter arrayAdapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1, array_list);
obj = (ListView)findViewById(R.id.listView1);
TextView emptyText = (TextView)findViewById(android.R.id.empty);
obj.setEmptyView(emptyText);
obj.setAdapter(arrayAdapter);
obj.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
// TODO Auto-generated method stub
int id_To_Search = arg2 + 1;
Bundle dataBundle = new Bundle();
dataBundle.putInt("id", id_To_Search);
Intent intent = new Intent(getApplicationContext(),DisplayContact.class);
intent.putExtras(dataBundle);
startActivity(intent);
}
});
content_scrolling.xml:
<android.support.v4.widget.NestedScrollView 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="uk.ac.tees.q5065885.diary.ScrollingActivity"
tools:showIn="#layout/activity_scrolling">
<android.support.v7.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
/>
</android.support.v7.widget.LinearLayoutCompat>
<TextView
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/emptyText"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
/>
</android.support.v4.widget.NestedScrollView>
Apologies for any mistakes, as I say, this is my second day; I'm learning as quick as I can!
You can create views programmatically and add them to LinearLayout on the fly. You can use any kind of view, but in this example I wanted to keep things clear so I assumed that your contacts are Strings and you want to just show them as TextViews. You can try something like this:
mydb = new DBHelper(this);
List<String> contacts = mydb.getAllCotacts();
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linear_layout);
for(String data : contacts) {
//Create a view for an LinearLayout
TextView textView = new TextView(this);
//Do whatever you like with a view - add listener, adjust style, add text etc.
textView.setOnClickListener(...);
textView.setText(data);
textView.setGravity(Gravity.CENTER);
//Add textView to linearLayout
linearLayout.addView(textView);
}
xml (not very pretty, customize it if you like :))
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="uk.ac.tees.q5065885.diary.ScrollingActivity"
tools:showIn="#layout/activity_scrolling">
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/linear_layout"
android:orientation="vertical"/>
</android.support.v4.widget.NestedScrollView>
When my application starts I want to have a start game button. When the button is pressed I want another activity to be shown.
In XML I Setup the button like this:
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Start"
android:id="#+id/bttnStart"
android:onClick="startGame"
/>
And this is the Java function:
public void startGame(View v ){
setContentView(R.layout.activity_start_menue);
}
My app crashes when I click the button.
Calling setContentView() multiple times is dangerous, and doesn't always work. There can be hierarchy conflicts, and inefficiencies that result from instantiating views multiple times. It's also not that helpful, because you're not in control of the container that the layout expands into.
Here is the proper way to do it.
Android provides a built-in mechanism for view-switching called a ViewFlipper. Instead of calling setContentView() for the layout you want to swap in, you can tell the ViewFlipper object to either showNext() or setDisplayedChild(int).
Here's how you would accomplish that in your main.xml.
<?xml version="1.0" encoding="utf-8"?>
<ViewFlipper xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/viewflipper"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- The ViewFlipper can change through its direct children -->
<!-- Child 0 -->
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Start"
android:id="#+id/bttnStart"
android:onClick="startGame"/>
<!-- Child 1 -->
<LinearLayout
android:id="#+id/activity_start_menu"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Here's the menu!"/>
</LinearLayout>
</ViewFlipper>
Note that the views being flipped through are direct children of the <ViewFlipper> that you are using. FYI, you can have more than just two views.
Now onto the Java code in your `MyActivity'.
public class MyActivity extends Activity {
ViewFlipper viewFlipper;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
viewFlipper = (ViewFlipper) findViewById(R.id.viewflipper);
}
/**
* Switches to the activity_start_menu LinearLayout
* specified in the ViewFlipper.
*/
public void startGame(View v) {
//First way -- use showNext() & showPrevious()
viewFlipper.showNext();
//Second way -- use setDisplayedChild(int) where int is
// the index of the view starting from 0
//In this case, there are two. 0 is the button,
// and 1 is the menu layout.
viewFlipper.setDisplayedChild(1);
//You can also do fancy animations to switch between views.
// Check out the methods accessible and experiment with them!
}
}
You should end up with something like this:
Start activity
Draft:
onCreate()
setContentView(//layout 1);
Button lButton = (Button) findview....
lButton.setOnClickListener(...)
{
onClick()
{
setContentView(//layout 2);
}
}
To start new activity you should use:
Intent intent = new Intent(this, YourActivity.class);
startActivity(intent);
Or if you wouldn't change activity use for eample viewswitcher to switch layout, fragments etc
Can someone tell me how should i create the above view here via xml or java coding in android?
This is what i have tried so far... But the view just seems to look too plain without any pictures by the side of each string as shown in the above link? What should i do to get the sort of more professional view?
final String [] items = new String []{"Details", "Delete File"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("File Options");
builder.setItems(items, new OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
if(arg1 == 0)
{
startActivity(new Intent(getApplicationContext(), DialogBox.class));
}
else
{
deleteFile();
}
}
});
builder.create().show();
You can check this code
This to show the dialog and code for each button,as we do in onCreate.
private void showRules() {
final Dialog ruleDialog = new Dialog(this);
ruleDialog.setContentView(R.layout.ruledialog);
Button cancelbtn = (Button)ruleDialog.findViewById(R.id.cancelbtn);
//cancelbtn.setOnClickListener(this);
cancelbtn.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
ruleDialog.dismiss();
}
});
ruleDialog.setCancelable(true);
ruleDialog.show();
//dialog.setTitle("How");
}
This the xml that I have use for it,
<?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">
<TextView
android:id="#+id/dialogHead"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="#string/dialogHead"
android:paddingBottom="20px"
android:layout_alignParentTop="true"
/>
<Button
android:id="#+id/cancelbtn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="#drawable/ic_cancel"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:paddingRight="3px"
android:paddingTop="3px"
/>
<ScrollView
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_below="#id/dialogHead"
>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="#string/dialogBody"
/>
</ScrollView>
</RelativeLayout>
I hope this will help you.
see here: http://developer.android.com/guide/topics/ui/dialogs.html#CustomDialog you can create your own layout and define what ever you'd like. as for professionalism - thats in the eye of the beholder.
Edit:
so don't use your string array to set your text.
create a layout that has a TextView ImageView TextView. use the layout inflator to inflate the view. find the 1st textview and setText("Details") (if you didn't do it statically in the xml)
find the second textview and setText("Delete") (if you didn't do it statically in the xml)
find the image and setImageResource (if you didn't do it statically in the xml)
set the builders view to your layout.
oh and maybe add some buttons with onclick listeners to do your stuff. or use an alertdialogbuilder.
I have set up four tabs that each hold a listview, I have added code in the listview java file to make the lists transparent, however, I have a semi transparent grey box covering 75% of the screen and I cannot figure out why, I have a background on my other listviews and they are completely transparent, but the lists within the tabhost have the grey box.
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="2dp">
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="3dp"
android:layout_weight="1"/>
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0"/>
</LinearLayout>
</TabHost>
import android.app.TabActivity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.widget.TabHost;
public class Tabs extends TabActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Resources res = getResources(); // Resource object to get Draw
TabHost tabHost = getTabHost(); // The activity TabHost
TabHost.TabSpec spec; // Reusable TabSpec for each tab
Intent intent; // Reusable Intent for each tab
// Create an Intent to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, prem.class);
// Initialise a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("Prem").setIndicator("Prem",
res.getDrawable(R.drawable.icontabs))
.setContent(intent);
tabHost.addTab(spec);
// Create an Intent to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, champ.class);
// Initialise a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("Champ").setIndicator("Champ",
res.getDrawable(R.drawable.champ))
.setContent(intent);
tabHost.addTab(spec);
// Do the same for the other tabs
intent = new Intent().setClass(this, l1.class);
spec = tabHost.newTabSpec("League 1").setIndicator("L",
res.getDrawable(R.drawable.l1))
.setContent(intent);
tabHost.addTab(spec);
intent = new Intent().setClass(this, ll2.class);
spec = tabHost.newTabSpec("l2").setIndicator("Le",
res.getDrawable(R.drawable.l2))
.setContent(intent);
tabHost.addTab(spec);
tabHost.setCurrentTab(0);
}
}
public class l1 extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Create an array of Strings, that will be put to our ListActivity
String[] names = new String[] {"Le"};
ListView lv = getListView();
lv.setBackgroundResource(R.drawable.le2);
lv.setCacheColorHint(00000000);
this.setListAdapter(new ArrayAdapter<String>(this,
R.layout.list_item, names));
}
// Get the item that was clicked
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
if (position == 0) {
In your layout XML file, your tab content (the FrameLayout) should be after the tab widget, not before. It's possible the box you are seeing is the tab widget's background.
Like this:
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
</TabHost>