How to create custom widget in Android? - android

I'm completely new to Android programming, so I'm not really sure what I should be searching for. I have a LinearLayout element on one of my activities.
<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="wrap_content"
android:layout_marginTop="15dp"
android:id="#+id/comment_area"
android:orientation="vertical"/>
I have a JSON array of comments (userName, commentText, commentDate) that I want to add into this LinearLayout though a loop. I created a comment_view.xml layout and created a CommentWidget class extending LinearLayout. Frankly I have no idea if this is the correct approach, and I don't think it is because I can't get the comments to load in.
My class is
public class CommentWidget extends LinearLayout {
private String text;
public void setText(String text) {
this.text = text;
}
public CommentWidget(Context context){
super(context);
}
public CommentWidget(Context context,AttributeSet attrs){
super(context,attrs);
}
#Override
protected void onFinishInflate(){
super.onFinishInflate();
TextView textView=(TextView) findViewById(R.id.comment_text);
textView.setText(text);
}
}
My widget layout is
<?xml version="1.0" encoding="utf-8"?>
<com.myproject.CommentWidget 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:id="#+id/comment_text"/>
</com.myproject.CommentWidget>
Inside my loop on the activity I was calling:
CommentWidget w = new CommentWidget(this);
w.setText(comment.getText());
mtxtArea.addView(w);
But nothing shows up. Can someone point me in the right direction? I'm correctly receiving the JSON into an array already.
Update: Answer
Windsurfer's answer below set me on the right track to use a ListView for what I am trying to accomplish. Using his links and some searching I found out that extending the ArrayAdapter is the most appropriate for JSON type data. I ended up following the tutorial at the following link
https://devtut.wordpress.com/2011/06/09/custom-arrayadapter-for-a-listview-android/

You can very well extend the LinearLayout to do this, but Android already has a couple of widgets designed for this. I believe you're looking for a ListView to display an array of data. Rather than creating a new widget, take a look at how a ListView works. A ListView uses an adapter to bind data to it. You will still have to design the layout for a single comment item, but a lot of the heavy lifting is done by the ListView and it's adapter.
Here are some links to get you started:
http://developer.android.com/guide/topics/ui/layout/listview.html
http://www.vogella.com/tutorials/AndroidListView/article.html
Take a look at this link by Romain Guy who introduces ListViews too.

Related

Android ListView/Recyclerview dynamic content

Hello I am iOS developer just started with android, I know basic concepts of android like RecyclerView, ListView.
I want to make a feed page in which each row can contain one photo and multiple comments, no of comments are dynamically changing depending on data.
How to achieve the same using RecyclerView/ListView?
I can achieve the same in iOS like this : http://t.co/z1IRHTTjED
If you already know concepts of ListView and RecyclerView you should know that we use Adapters to provide views for List.
You can create a custom Adapter which will create a view, where, depends on data you have, you will display comments or not.
Edit.
For example you have a layout like this
<LinearLayout>
<ImageView />
<TextView android:id="#+id/comments" />
</LinearLayout>
in your adapter you should call
TextView comments = (TextView) findViewById(R.id.comments);
if(haveComments) {
comments.setVisibility(View.VISIBLE);
//display comments
} else {
comments.setVisibility(View.GONE);
}
If you need to have more complex layout for comments, for example with images, and date field, instead of TextView declare LinearLayout with vertical orientation. You can fill it with items from code.
LinearLayout commentsLayout = (LinearLayout) findViewById(R.id.commentsLayout);
if(haveComments) {
comments.setVisibility(View.VISIBLE);
//display comments
commentsLayout.addView(inflateCommentView());
} else {
comments.setVisibility(View.GONE);
}
private View inflateCommentView() {
View myComment = LayoutInflater.from(context).inflate(R.layout.my_complex_comment, null);
//set listeners, fill with data
return myComment;
}

How to change a TextView's text from a custom View?

I'm actually trying to build my first android app, and I just encountered a problem I can't figure out.
I have in my XML two views, one is a plain basic TextView :
<TextView
android:id="#+id/tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
/>
and the other one is a custom class I built :
<com.package.testpanel.Panel
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
The code of this "Panel" is quite simple :
public class Panel extends View implements OnTouchListener, OnGestureListener {
TextView tv;
public Panel(Context context, AttributeSet attrs) {
super(context, attrs);
tv = (TextView) findViewById(R.id.tv);
if (tv != null) {
tv.setText("Text changed");
}
}
}
(I have of course implemented all the Listeners method)
As you can see in my constructor, I'm just trying to change the TextView's text from my Panel, and it won't work. If I don't put the "if (tv != null)" condition, the app just
crash at launch.
I tried putting this piece of code in one of the listener's method instead of the constructor, and it's the same result : nothing happen or it crashes without the if condition.
If I put the exact same code in the Activity's onCreate, it works perfectly, but my goal is to change the text/properties of the TextView based on the touch and gesture listener on my panel.
I'm really new to this android SDK, I have yet to try how to debug an app, but for now I would just like to know why this simple code isn't working.
So if anyone has an idea as why I can't do that, or a work-around, I'd be much obliged !
Yes. We should first load the main layout before trying to get the sub-view. This is usually with following statement:
setContentView(R.layout.your_layout);
Please refer to http://developer.android.com/reference/android/app/Activity.html
Also I suggest you firstly spend some time on the basic concept before trying to create complicated app. This will save you lots of time to finger out those questions.
AddsetContentView(R.layout.your_filename_with_textview); before tv = (TextView) findViewById(R.id.tv);

Custom ListView layout crashes my activity

I am starting out on Android and trying to make a custom ListView layout. I've followed some guides and have made the following code:
public class CheckInList extends ListActivity {
...
#Override
public void onCreate(Bundle savedInstanceState) {
...
mAdapter = new ArrayAdapter<String>(this, R.layout.checkinlist_item, R.id.checkinlist_item_text, mNames);
setListAdapter(mAdapter);
...
}
}
This is the code for checkinlist_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/checkinlist_item_bg">
<TextView android:id="#+id/checkinlist_item_text"
style="#style/RegisterText" />
</RelativeView>
If I use android.R.layout.simple_list_item_1 instead of my above template then everything is fine and my ListView works, however whenever I use the above code my activity crashes. I am running things on Android 1.5.
Any ideas why things are crashing?
Could it be because RelativeView does not exist?
I might suggest adding the attributes android:layout_width="fill_parent" and android:layout_height="fill_parent" or set them to whatever you want, but those are required. And yes, use RelativeLayout as Matthew said, since RelativeView doesn't exist.
at first sight there is no width/height values for your textView ?

textView.setText(); crashes

The setText() method returns null in my application why?
public class GetValue extends Activity {
char letter = 'g';
int ascii = letter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView = (TextView)findViewById(R.id.txt_1);
textView.setText(ascii);
}
}
It doesn't matter what text i put in, it crashes anyway. Why does setText() keep returning null?
Thank you, in advance
Solution: My error was in the xml file. I wrote:
android:text="#+id/txt_1"
When it should say:
android:id="#+id/txt_1"
Thanks a lot for all the answers and comments!
You tried to pass an integer as parameter to setText, which assumes it is a resource ID. To display computed text, pass it as a string: textView.setText("g");
Edited: Check your XML file, I have test with something very basic and it works
<?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">
<TextView
android:id="#+id/txt_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="myTextView"/>
</LinearLayout>
Maybe try to clean your project (Project->Clean in Eclipse), I recently have some trouble with R generation on the last ADT version.
Try this:
textView.setText(Integer.toString(ascii));
Also make sure that your layout xml has TextView txt_1
I've tried :
Integer.toString(char) and String.valueOf(char)
both didnt work.
The only solution is :
txt.setText(""+char);
This is not very efficient from optimization point of view but it does the trick :)

Android AutoCompleteTextView onClick problem

I've created an AutoCompleteTextView to search through a list of course titles (obtained from an sqlite db) and what I want to do is, when the user clicks on a title from the drop-down menu, the whole information from the database about his selection appears in a text view created below the AutoCompleteTextView.
I am pretty new to programming, especially for android and I would really appreciate it if someone could explain me how exactly to use setOnItemClickListener to call an instance in the database in the TextView below.
The code for the layout (R.layout.main_courses) is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<AutoCompleteTextView
android:id="#+id/autocomplete_course"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Search for a course"/>
<TextView
android:id="#+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/autocomplete_course"
android:hint="Information about the course will appear here" />
</RelativeLayout>
and the code for the AutoCompleteTextView I've written so far is:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_courses);
DataBase db = new DataBase(this.getApplicationContext());
db.openDataBase();
ArrayList<String> aCourses = db.getCoursesArr();
db.close();
AutoCompleteTextView search = (AutoCompleteTextView) findViewById(R.id.autocomplete_course);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_courses, aCourses);
search.setAdapter(adapter);
}
First of all you should try using a CursorAdapter instead of getting an array from it. Check this link for more info.
There is a method in AutoCompleteTextView that let you decide how many letters the user must type before the dropdown is shown, setThreshold. The issue is that it only allows >=1 values.
If you check this class src code, the good news is that the variable set by setThreshold() is only used in this method:
public boolean enoughToFilter() {
return getText().length() >= mThreshold;
}
So the first thing I would try is extending AutoCompleteTextView and override that method to always return true.
NOTE: Keep in mind that this might change in the future and it can get broken.

Categories

Resources