how to implement TextWatcher when my Json is ready? - java

I am newbie in Android development, and currently I am facing problem with my project, I want to connect my app to local host, I have seen the ways to do that and picked up the simplest one using json, thus I stopped on the way of implementing my TextWatcher adding it in to that code. The rest of the things I have done as it requires on steps.
Please take a look at my code and tell me what is my mistake?
this is my Java code:
public class MyActivity extends Activity implements TextWatcher {
HttpClient httpClient;
private HttpPost mhttpPost;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String[] mobileArray = {"Laptops","IPhone","WindowsMobile","Blackberry","WebOS","Ubuntu","Windows7","Max OS X"};
ArrayAdapter adapter = new ArrayAdapter<String>(this,R.layout.list_item,mobileArray);
ListView listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter);
httpClient = new DefaultHttpClient();
mhttpPost = new HttpPost("http://10.0.2.1/index/get_for_mobile");
try {
HttpResponse response = httpClient.execute(mhttpPost);
HttpEntity ent = response.getEntity();
String temp = EntityUtils.toString(response.getEntity());
}
catch (Exception e ){}
}
private TextWatcher search = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
}
};
}
and here is my xml code:
<!-- The primary full-screen view. This can be replaced with whatever view
is needed to present your content, e.g. VideoView, SurfaceView,
TextureView, etc. -->
<!-- This FrameLayout insets its children based on system windows using
android:fitsSystemWindows. -->
<SearchView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/searchView"
android:layout_marginBottom="48dp" />
<ListView
android:layout_width="wrap_content"
android:layout_height="399dp"
android:id="#+id/listView"
android:layout_gravity="right|top"
android:choiceMode="multipleChoice" android:clickable="true"/>

you have not added textwatcher to EditText or any View ,of which text event you want handle .see http://developer.android.com/reference/android/text/TextWatcher.html
Why you need to implement textwacther whicile ending json to localhost .

Related

How to show a page number on every page in a PDF using voghDev/PdfViewPager library?

It's been days of researching and I cannot figure out a way to do it.
Here is the link of the library on Github. Library
public class PDFViewActivity1 extends AppCompatActivity {
LinearLayout root;
EditText etPdfUrl;
Button btnDownload;
PDFPagerAdapter adapter;
String id;
ArrayList<String> topicLink;
File file;
String filePath;
PDFViewPager pdfViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
setContentView(R.layout.activity_p_d_f_view);
root = (LinearLayout) findViewById(R.id.remote_pdf_root);
final Context ctx = this;
Intent intent = getIntent();
String str = intent.getStringExtra("filePath");
str = str; // This contains the path of the PDF on my device
Log.i("filePathInString", str);
pdfViewPager = new PDFViewPager(ctx, str);
pdfViewPager.setId(R.id.pdfViewPager);
pdfViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
adapter = new PDFPagerAdapter(ctx, str);
pdfViewPager.setAdapter(adapter);
root.removeAllViewsInLayout();
root.addView(pdfViewPager,
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
}
#Override
protected void onDestroy() {
super.onDestroy();
((PDFPagerAdapter) pdfViewPager.getAdapter()).close();
}
}
The PDF renders perfectly form my device but I cannot see the page numbers, title , total pages of the PDF when the PDF is loaded.
This is my XML file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/remote_pdf_root"
android:orientation="vertical"
android:background="#FFFFFF"
tools:context=".PDFViewActivity1"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<es.voghdev.pdfviewpager.library.PDFViewPager
android:id="#+id/pdfViewPager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
What do I do when the page is scrolled, I cannot figure out a thing , I tried a lot of methods of the PDFAdapter but I an unsuccessful :( How can I do the task ?
RelativeLayout remotePdfRoot = findViewById(R.id.remote_pdf_root);
remotePDFViewPager = new RemotePDFViewPager(this, downloadFileUrlConnection, url, listener);
remotePDFViewPager.setId(R.id.pdfViewPager);
//after file loading success
PDFPagerAdapter adapter = new PDFPagerAdapter(this, FileUtil.extractFileNameFromURL(url));
remotePDFViewPager.setAdapter(adapter);
updateLayout();
private void updateLayout() {
remotePdfRoot.removeAllViewsInLayout();
remotePdfRoot.addView(remotePDFViewPager, LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
}
I preview pdf this way and there will be a pagenumber.
You can use https://github.com/barteksc/AndroidPdfViewer library for this and you can get the page count by
`vpPdf.fromAsset("sample.pdf").onError {
Log.i(TAG, "${it.localizedMessage}")
it.printStackTrace()
}.onPageError { _, t ->
t.printStackTrace()
}.enableSwipe(true).swipeHorizontal(true).onPageChange { page, pageCount ->
//here page count is count of page user currently is viewing.
}.load()`
I had to use this lib at work and it is working perfectly fine!!
The above code is from kotlin but you can convert it to java i guess,If you are not able to convert it the kindly comment so i will help you with that too!!.

EditText: Cursor does not update when calling setText() with a custom Editable

I'm experiencing issues trying to use a custom type that implements Editable as the basis for an EditText. Here is my code:
// This is a custom type that implements Editable.
// It's just a wrapper over a SpannableStringBuilder, with some
// irrelevant added functionality.
public class ColoredText implements Editable {
private final SpannableStringBuilder builder;
public ColoredText(String text) {
this.builder = new SpannableStringBuilder(text);
}
// All Editable methods are implemented through this.builder.
#Override
public Editable replace(int i, int i1, CharSequence charSequence, int i2, int i3) {
this.builder.replace(i, i1, charSequence, i2, i3);
return this;
}
...
}
public class NoCopyEditableFactory extends Editable.Factory {
#Override
public Editable newEditable(CharSequence source) {
return (Editable) source;
}
}
// In MainActivity.java
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.main);
String line = "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE";
String text = TextUtils.join("\n", Collections.nCopies(100, line));
Editable e = new ColoredText(text);
EditText et = (EditText) findViewById(R.id.editText);
et.setEditableFactory(new NoCopyEditableFactory()); // This line is causing trouble.
et.setText(e, TextView.BufferType.EDITABLE);
}
// In the MainActivity layout file
<EditText
android:id="#+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
For some reason, when I comment out the NoCopyEditableFactory, the cursor updates just fine. However, when I uncomment the line forcing the EditText not to copy the ColoredText into a new SpannableStringBuilder, the cursor does not update when I click on new places in the text. Why is this?
The problem turned out to be with my Editable implementation. It works fine after I deleted some misbehaving code.

Android ListView not refreshing after dataset changed, though I have used the Adapter.notifyDataSetChanged()

I know similar questions had been asked here a couple of times, but none of them could help me with my problem, so I will just have to ask again.
What I have is an app that has a fragment that holds a ListView in the main activity and I used a PullableListView so that when I drag the ListView up, it will trigger the onLoadMore() callback method to load more data from the server. Once data loaded, the data will be saved to a SQLiteDB and then used by the ListView to show the updated data.
The is my PullableListViewFragment.java:
public class PullableListViewFragment extends Fragment implements
OnItemClickListener {
private ListView listView;
private PullToRefreshLayout ptrl;
private MissionDB mMissionDB;
private List<MissionEntity> mData;
private MissionListAdapter mAdapter;
/**
* Specify the exact mission that will be displayed in MissionDetailActivity
*/
private int mIndexOfMission;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View pullableLayout = inflater.inflate(R.layout.pullable_layout, container, false);
listView = (ListView) pullableLayout.findViewById(R.id.content_view);
listView.setDivider(null);
ptrl = (PullToRefreshLayout) pullableLayout.findViewById(R.id.refresh_view);
ptrl.setOnRefreshListener(new RefreshListener());
loadData();
Log.d(Constants.LOG_TAG, "onCreateView Called from PullableListViewFragment");
return pullableLayout;
}
/**
* Initialise ListView
*/
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mAdapter = new MissionListAdapter(getActivity(), mData);
listView.setAdapter(mAdapter);
listView.setOnItemClickListener(this);
mAdapter.notifyDataSetChanged();
Log.d(Constants.LOG_TAG, "onActivityCreated Called from PullableListViewFragment");
}
/**
* Load data from db
*/
private void loadData() {
mData = new ArrayList<>();
mMissionDB = MissionDB.getInstance(MyApplication.getContext());
mData = mMissionDB.loadMission();
}
/**
* OnItemClick event
*/
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Intent intent = new Intent(getActivity(), MissionDetailActivity.class);
mIndexOfMission = mData.get((int) id).getId();
intent.putExtra("Position", mIndexOfMission);
startActivity(intent);
}
}
And this is the RefreshListener.java:
public class RefreshListener implements PullToRefreshLayout.OnRefreshListener {
private MissionDB mMissionDB = MissionDB.getInstance(MyApplication.getContext());
#Override
public void onLoadMore(final PullToRefreshLayout pullToRefreshLayout) {
// LoadMore
new Handler() {
#Override
public void handleMessage(Message msg) {
/** When drag up, load more mission that is older and not out of date */
mMissionDB.open();
int id = mMissionDB.getMaxOrMinId("MIN");
final JSONObject oldMission = new JSONObject();
try {
oldMission.put("platform", "1");
oldMission.put("more", 0);
oldMission.put("id", id);
oldMission.put("size", 1);
} catch (JSONException e) {
e.printStackTrace();
}
Thread t = new Thread(new Runnable() {
#Override
public void run() {
HttpRequest.sendHttpRequest(Constants.PULLORDRAG_TO_LOAD_MISSION_URL, oldMission, new HttpCallbackListener() {
#Override
public void onFinish(String response) {
MissionEntity mMission = new MissionEntity();
/** Save new mission to mission database */
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray missionList = jsonObject.getJSONArray("taskList");
for (int i = 0; i < missionList.length(); i++) {
JSONObject mission = missionList.getJSONObject(i);
mMission.setId(mission.getInt("id"));
mMission.setDownloadUrl(mission.getString("appPath"));
mMission.setCreateTime(mission.getString("taskId"));
mMission.setImageUrl(mission.getString("appImg"));
mMission.setTitleName(mission.getString("appName"));
mMission.setRemainTime("Remain: 1d 11h 23m 36s");
mMission.setParticipant("135");
mMission.setCreator("Google");
mMission.setRequirement(mission.getString("description"));
mMission.setRewards("TODO");
mMission.setAttention("TODO");
mMission.setValidDate(mission.getString("deadline"));
mMission.setAccepted("0");
mMission.setCollected("0");
mMission.setAccomplished("0");
mMissionDB.saveMission(mMission);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onError(Exception e) {
e.printStackTrace();
Log.e(Constants.LOG_TAG, "Error while loading more");
}
});
}
});
try {
t.start();
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
pullToRefreshLayout.loadmoreFinish(PullToRefreshLayout.SUCCEED);
//==================Update 1==================
ListView list = (ListView) pullToRefreshLayout.findViewById(R.id.content_view);
List<MissionEntity> missionList = mMissionDB.loadMission();
Log.d(Constants.LOG_TAG, "mission size" + missionList.size());
MissionListAdapter adapter = (MissionListAdapter) list.getAdapter();
adapter.setData(missionList);
adapter.notifyDataSetChanged();
list.setAdapter(adapter);
//==================Update 1==================
}
}.sendEmptyMessageDelayed(0, 1000);
}
}
The PullToRefreshLayout is a custom RelativeLayout that defined a inner interface OnRefreshListener that will be called once the onLoadMore() callback method is called.
The ListView I use in the Fragment is a PullableListView that implemented a Pullable interface that can drag up.
My Pullable.java:
public interface Pullable
{
/**
* If pull up is not needed, set canPullUp to false
*
* #return true if the View can pull up
*/
boolean canPullUp();
}
This is the fragment's layout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f2f2f2"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="5dp" />
<pulltorefresh.PullToRefreshLayout
android:id="#+id/refresh_view"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/refresh_head"/>
<!-- Supports all view that implemented the Pullable interface -->
<pulltorefresh.PullableListView
android:id="#+id/content_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<include layout="#layout/load_more"/>
</pulltorefresh.PullToRefreshLayout>
</LinearLayout>
The problem is when the data in the SQLiteDB is changed after the onLoadMore() method, the ListView in the fragment doesn't refresh itself unless I navigate to another fragment within the same main activity and then navigate back.
I tired all the ways I can find here and none of them help.
Could anyone tell me how can I make the ListView refresh itself when the data in the SQLiteDB changed.
[Update 1] I've added some code in the onLoadMore() callback, the size of the data remains the same after I get some data from the server, i think this is the problem why the ListVie is not refreshing, what's interesting is if I put a Thread.sleep(500) before mMission.loadMission() the size of the data is correct and everything is fine. Any idea why?
In onLoadMore method, you just only load data and save into database. After load data, you should update the data source of the adapter and call adapter.notifyDataSetChanged() to refresh the listview. or you can notify the fragment to reload data from database.
Make sure it get data when load more first. And I think your mMissionDB is changed indeed, but what about mData? Your adapter is use mData as datasource actually, so you should update mData, and call adapter.notifyDataSetChanged() to refresh the listview. Hope it can help you.

Button properties won't change

So I have an android app (java in Eclipse) and I want to change the text of some buttons on a keyboard through a shift method. I implemented the same code as I did to change a textview text, the same as everyone says to on similar questions, but for some reason it WILL NOT work. For some reason, after testing other button functions, I've determined that there's something it doesn't like about me changing ANY property of the button. Tried cleaning the project, didn't help. Keep getting an invocation exception. Here is relevant code:
public class MainActivity extends Activity {
boolean shift = true;
static Vector<String> answer = new Vector<String>(1, 1);
static int ansLength = 0;
private TextView answerbox;
private Button a;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initializeButtons();
setContentView(R.layout.activity_main);
answerbox = (TextView) findViewById(R.id.answerbox);
}
#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;
}
public void initializeButtons() {
a = (Button) findViewById(R.id.a);
}
public void typeKey(View sender) {
Button pressed = (Button) sender;
answer.add(ansLength, (String) pressed.getText());
//answerbox.setText("test string");
ansLength++;
StringBuilder stringBuilder = new StringBuilder();
for (String string : answer) {
stringBuilder.append(string);
}
answerbox.setText(stringBuilder.toString());
}
public void backSpace(View sender) {
answer.remove(ansLength - 1);
ansLength--;
StringBuilder stringBuilder = new StringBuilder();
for (String string : answer) {
stringBuilder.append(string);
}
answerbox.setText(stringBuilder.toString());
}
public void shift(View sender) {
if (shift == true) {
shift = false;
a.setText("l");
}
}
}
XML below:
<Button
android:id="#+id/a"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="A"
android:onClick="typeKey"/>
<Button
android:id="#+id/shift1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="^"
android:textSize="24sp"
android:onClick="shift" />
First, findViewById() in initializeButtons() should be called after setContentView() since there is no layout data in Activity object before setContentView()
Therefore, move the statement as following:
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeButtons(); // Move this.
answerbox = (TextView) findViewById(R.id.answerbox);
Second, I'd like to advise you that do not use Vector in Java except in a special purpose. Use ArrayList instead. Vector in Java is slow, and almost deprecated. It is just available because of compatibility issues.
static Vector<String> answer = new Vector<String>(1, 1);
should be replaced to
static ArrayList<String> answer = new ArrayList<String>(1, 1);
If you have sync issues, (I don't think you have this issue now) then use Collections.synchronizedList() method: Why is Java Vector class considered obsolete or deprecated?

Keep state of selected elements when data are changing in ListView

I have an activity with a list of Products (like a shopping list), in which we can choose the number of product units.
The activity contains EditText with TextWatcher and a ListView with a personal Adapter (extends BaseAdapter).
When I type a key in the EditText, the listView of products is refreshed with the new data.
But I would like to keep the state of my selected data.
For example, I type a reference in the EditText, then the listView contains 3 datas (A, B, C), I choose A, and type 5 units of it, then I type a new reference in the EditText (A and B disappears).
The listView contain only C, but I remove my search and go back to A, B, C.
the problem, the product A is unselected and have 0 of units (the 5 units have disappeared).
I would like to keep the selected products and the units even if I change my search in the EditText.
How to do that please ?
Here is a code snippet :
The layout of the activity :
<?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="match_parent"
android:orientation="vertical" >
<EditText
android:id="#+building_list/search_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Filter by reference"
android:inputType="textAutoCorrect|none|textAutoComplete|none|textNoSuggestions"
android:maxLines="1"
android:textSize="20dp" />
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="10dp"
android:id="#+id/productListView">
</ListView>
</LinearLayout>
The Adapter :
public class AdapterProduct extends BaseAdapter {
private List<Product> lstProduct;
private LayoutInflater mInflater;
public AdapterProduct(Context context, List<Product> listP) {
lstProduct = listP;
mInflater = LayoutInflater.from(context);
}
public View getView(int position, View convertView, ViewGroup parent) {
CheckedLinearLayout layoutItem;
if (convertView == null) {
layoutItem = (CheckedLinearLayout) mInflater.inflate(R.layout.row_product, parent, false);
final ViewHolderProduct viewHolder;
viewHolder = new ViewHolderProduct();
viewHolder.btPlusAmount = (Button)layoutItem.findViewById(R.id.btPlusAmount);
viewHolder.btPlusAmount.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Product p = (Product) viewHolder.product.getTag();
p.setAmount(p.getAmount()+1);
notifyDataSetChanged();
}
});
}
else {
layoutItem = (CheckedLinearLayout) convertView;
((ViewHolderProduct) layoutItem.getTag()).btPlusAmount.setTag(lstProduct.get(position));
}
ViewHolderProduct viewHolder = (ViewHolderProduct) layoutItem.getTag();
viewHolder.amount.setText(String.valueOf(lstProduct.get(position).getAmount()));
}
static class ViewHolderProduct {
protected TextView amount;
protected Button btPlusAmount;
}
}
And the AsyncTask with TextWatcher :
AsyncTask
doInBackground =>
modelProduct = new AdapterProduct(leContext,
ProductJSON.getService().searchProducts(leContext, url, params[0])); //params[0] = the text of EditText
private TextWatcher filterTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
//AsyncTask task
task.execute(s.toString());
}
};
I let you check my answer here.
1) Basically, add a new attribute to your adapter. A simple int[] is enough. Store the number of products selected inside.
2) Each time you build the View of a row of your ListView, check the number of products selected.
3)Make sure to update the number of products selected when you click on the button. Also, make sure to resize/update this array when your List changes. Call notifyDataSetChanged() Each Time you click on a product.

Categories

Resources