Skip to content

Commit dfe7683

Browse files
author
Lyla
committed
TFCM.00-StartingCode
1 parent 117fb37 commit dfe7683

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+812
-16
lines changed

app/build.gradle

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
apply plugin: 'com.android.application'
2+
apply plugin: 'android-apt'
23

34
android {
45
compileSdkVersion 25
5-
buildToolsVersion "25.0.1"
6+
buildToolsVersion "25.0.2"
67
defaultConfig {
78
applicationId "android.example.com.squawker"
8-
minSdkVersion 15
9+
minSdkVersion 16
910
targetSdkVersion 25
1011
versionCode 1
1112
versionName "1.0"
@@ -26,4 +27,14 @@ dependencies {
2627
})
2728
compile 'com.android.support:appcompat-v7:25.1.0'
2829
testCompile 'junit:junit:4.12'
30+
31+
// RecyclerView
32+
compile 'com.android.support:recyclerview-v7:25.1.0'
33+
34+
// Schematic dependencies for ContentProvider
35+
apt 'net.simonvt.schematic:schematic-compiler:0.6.3'
36+
compile 'net.simonvt.schematic:schematic:0.6.3'
37+
38+
// Preferences Dependencies
39+
compile 'com.android.support:preference-v7:25.1.0'
2940
}

app/src/main/AndroidManifest.xml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,37 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
package="android.example.com.squawker">
44

5+
<uses-permission android:name="android.permission.INTERNET" />
6+
57
<application
68
android:allowBackup="true"
79
android:icon="@mipmap/ic_launcher"
810
android:label="@string/app_name"
911
android:supportsRtl="true"
1012
android:theme="@style/AppTheme">
11-
<activity android:name=".MainActivity">
13+
<activity
14+
android:name=".MainActivity">
15+
1216
<intent-filter>
1317
<action android:name="android.intent.action.MAIN" />
1418

1519
<category android:name="android.intent.category.LAUNCHER" />
1620
</intent-filter>
1721
</activity>
22+
23+
<provider
24+
android:name=".provider.generated.SquawkProvider"
25+
android:authorities="android.example.com.squawker.provider.provider"
26+
android:exported="false" />
27+
28+
<activity
29+
android:name=".following.FollowingPreferenceActivity"
30+
android:parentActivityName=".MainActivity">
31+
<meta-data
32+
android:name="android.support.PARENT_ACTIVITY"
33+
android:value=".MainActivity" />
34+
</activity>
35+
1836
</application>
1937

2038
</manifest>

app/src/main/ic_launcher-web.png

29.6 KB
Loading
Lines changed: 123 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,134 @@
1+
/*
2+
* Copyright (C) 2017 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
package android.example.com.squawker;
218

3-
import android.support.v7.app.AppCompatActivity;
19+
import android.content.Intent;
20+
import android.database.Cursor;
21+
import android.example.com.squawker.following.FollowingPreferenceActivity;
22+
import android.example.com.squawker.provider.SquawkContract;
23+
import android.example.com.squawker.provider.SquawkProvider;
424
import android.os.Bundle;
25+
import android.support.v4.app.LoaderManager;
26+
import android.support.v4.content.CursorLoader;
27+
import android.support.v4.content.Loader;
28+
import android.support.v7.app.AppCompatActivity;
29+
import android.support.v7.preference.PreferenceManager;
30+
import android.support.v7.widget.DividerItemDecoration;
31+
import android.support.v7.widget.LinearLayoutManager;
32+
import android.support.v7.widget.RecyclerView;
33+
import android.util.Log;
34+
import android.view.Menu;
35+
import android.view.MenuInflater;
36+
import android.view.MenuItem;
37+
38+
public class MainActivity extends AppCompatActivity implements
39+
LoaderManager.LoaderCallbacks<Cursor> {
40+
41+
private static String LOG_TAG = MainActivity.class.getSimpleName();
42+
private static final int LOADER_ID_MESSAGES = 0;
43+
44+
RecyclerView mRecyclerView;
45+
LinearLayoutManager mLayoutManager;
46+
SquawkAdapter mAdapter;
47+
48+
static final String[] MESSAGES_PROJECTION = {
49+
SquawkContract.COLUMN_AUTHOR,
50+
SquawkContract.COLUMN_MESSAGE,
51+
SquawkContract.COLUMN_DATE,
52+
SquawkContract.COLUMN_AUTHOR_KEY
53+
};
54+
55+
static final int COL_NUM_AUTHOR = 0;
56+
static final int COL_NUM_MESSAGE = 1;
57+
static final int COL_NUM_DATE = 2;
58+
static final int COL_NUM_AUTHOR_KEY = 3;
559

6-
public class MainActivity extends AppCompatActivity {
760

861
@Override
962
protected void onCreate(Bundle savedInstanceState) {
1063
super.onCreate(savedInstanceState);
1164
setContentView(R.layout.activity_main);
65+
66+
mRecyclerView = (RecyclerView) findViewById(R.id.squawks_recycler_view);
67+
68+
// Use this setting to improve performance if you know that changes
69+
// in content do not change the layout size of the RecyclerView
70+
mRecyclerView.setHasFixedSize(true);
71+
72+
// Use a linear layout manager
73+
mLayoutManager = new LinearLayoutManager(this);
74+
mRecyclerView.setLayoutManager(mLayoutManager);
75+
76+
// Add dividers
77+
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(
78+
mRecyclerView.getContext(),
79+
mLayoutManager.getOrientation());
80+
mRecyclerView.addItemDecoration(dividerItemDecoration);
81+
82+
// Specify an adapter
83+
mAdapter = new SquawkAdapter();
84+
mRecyclerView.setAdapter(mAdapter);
85+
86+
// Start the loader
87+
getSupportLoaderManager().initLoader(LOADER_ID_MESSAGES, null, this);
88+
89+
}
90+
91+
@Override
92+
public boolean onCreateOptionsMenu(Menu menu) {
93+
MenuInflater inflater = getMenuInflater();
94+
inflater.inflate(R.menu.main_menu, menu);
95+
return true;
96+
}
97+
98+
@Override
99+
public boolean onOptionsItemSelected(MenuItem item) {
100+
int id = item.getItemId();
101+
if (id == R.id.action_following_preferences) {
102+
// Opens the following activity when the menu icon is pressed
103+
Intent startFollowingActivity = new Intent(this, FollowingPreferenceActivity.class);
104+
startActivity(startFollowingActivity);
105+
return true;
106+
}
107+
return super.onOptionsItemSelected(item);
108+
}
109+
110+
111+
/**
112+
* Loader callbacks
113+
*/
114+
115+
@Override
116+
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
117+
// This method generates a selection off of only the current followers
118+
String selection = SquawkContract.createSelectionForCurrentFollowers(
119+
PreferenceManager.getDefaultSharedPreferences(this));
120+
Log.d(LOG_TAG, "Selection is " + selection);
121+
return new CursorLoader(this, SquawkProvider.SquawkMessages.CONTENT_URI,
122+
MESSAGES_PROJECTION, selection, null, SquawkContract.COLUMN_DATE + " DESC");
123+
}
124+
125+
@Override
126+
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
127+
mAdapter.swapCursor(data);
128+
}
129+
130+
@Override
131+
public void onLoaderReset(Loader<Cursor> loader) {
132+
mAdapter.swapCursor(null);
12133
}
13134
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*
2+
* Copyright (C) 2017 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package android.example.com.squawker;
18+
19+
import android.database.Cursor;
20+
import android.example.com.squawker.provider.SquawkContract;
21+
import android.support.v7.widget.RecyclerView;
22+
import android.view.LayoutInflater;
23+
import android.view.View;
24+
import android.view.ViewGroup;
25+
import android.widget.ImageView;
26+
import android.widget.TextView;
27+
28+
import java.text.SimpleDateFormat;
29+
import java.util.Date;
30+
31+
/**
32+
* Converts cursor data for squawk messages into visible list items in a RecyclerView
33+
*/
34+
public class SquawkAdapter extends RecyclerView.Adapter<SquawkAdapter.SquawkViewHolder> {
35+
36+
37+
private Cursor mData;
38+
private static SimpleDateFormat sDateFormat = new SimpleDateFormat("dd MMM");
39+
40+
41+
private static final long MINUTE_MILLIS = 1000 * 60;
42+
private static final long HOUR_MILLIS = 60 * MINUTE_MILLIS;
43+
private static final long DAY_MILLIS = 24 * HOUR_MILLIS;
44+
45+
46+
@Override
47+
public SquawkViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
48+
View v = LayoutInflater.from(parent.getContext())
49+
.inflate(R.layout.item_squawk_list, parent, false);
50+
51+
SquawkViewHolder vh = new SquawkViewHolder(v);
52+
return vh;
53+
}
54+
55+
@Override
56+
public void onBindViewHolder(SquawkViewHolder holder, int position) {
57+
mData.moveToPosition(position);
58+
59+
String message = mData.getString(MainActivity.COL_NUM_MESSAGE);
60+
String author = mData.getString(MainActivity.COL_NUM_AUTHOR);
61+
String authorKey = mData.getString(MainActivity.COL_NUM_AUTHOR_KEY);
62+
63+
// Get the date for displaying
64+
long dateMillis = mData.getLong(MainActivity.COL_NUM_DATE);
65+
String date = "";
66+
long now = System.currentTimeMillis();
67+
68+
// Change how the date is displayed depending on whether it was written in the last minute,
69+
// the hour, etc.
70+
if (now - dateMillis < (DAY_MILLIS)) {
71+
if (now - dateMillis < (HOUR_MILLIS)) {
72+
long minutes = Math.round((now - dateMillis) / MINUTE_MILLIS);
73+
date = String.valueOf(minutes) + "m";
74+
} else {
75+
long minutes = Math.round((now - dateMillis) / HOUR_MILLIS);
76+
date = String.valueOf(minutes) + "h";
77+
}
78+
} else {
79+
Date dateDate = new Date(dateMillis);
80+
date = sDateFormat.format(dateDate);
81+
}
82+
83+
// Add a dot to the date string
84+
date = "\u2022 " + date;
85+
86+
holder.messageTextView.setText(message);
87+
holder.authorTextView.setText(author);
88+
holder.dateTextView.setText(date);
89+
90+
// Choose the correct, and in this case, locally stored asset for the instructor. If there
91+
// were more users, you'd probably download this as part of the message.
92+
switch (authorKey) {
93+
case SquawkContract.ASSER_KEY:
94+
holder.authorImageView.setImageResource(R.drawable.asser);
95+
break;
96+
case SquawkContract.CEZANNE_KEY:
97+
holder.authorImageView.setImageResource(R.drawable.cezanne);
98+
break;
99+
case SquawkContract.JLIN_KEY:
100+
holder.authorImageView.setImageResource(R.drawable.jlin);
101+
break;
102+
case SquawkContract.LYLA_KEY:
103+
holder.authorImageView.setImageResource(R.drawable.lyla);
104+
break;
105+
case SquawkContract.NIKITA_KEY:
106+
holder.authorImageView.setImageResource(R.drawable.nikita);
107+
break;
108+
default:
109+
holder.authorImageView.setImageResource(R.drawable.test);
110+
}
111+
}
112+
113+
@Override
114+
public int getItemCount() {
115+
if (null == mData) return 0;
116+
return mData.getCount();
117+
}
118+
119+
public void swapCursor(Cursor newCursor) {
120+
mData = newCursor;
121+
notifyDataSetChanged();
122+
}
123+
124+
public class SquawkViewHolder extends RecyclerView.ViewHolder {
125+
final TextView authorTextView;
126+
final TextView messageTextView;
127+
final TextView dateTextView;
128+
final ImageView authorImageView;
129+
130+
public SquawkViewHolder(View layoutView) {
131+
super(layoutView);
132+
authorTextView = (TextView) layoutView.findViewById(R.id.author_text_view);
133+
messageTextView = (TextView) layoutView.findViewById(R.id.message_text_view);
134+
dateTextView = (TextView) layoutView.findViewById(R.id.date_text_view);
135+
authorImageView = (ImageView) layoutView.findViewById(
136+
R.id.author_image_view);
137+
}
138+
}
139+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (C) 2017 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package android.example.com.squawker.following;
17+
18+
import android.example.com.squawker.R;
19+
import android.os.Bundle;
20+
import android.support.v4.app.NavUtils;
21+
import android.support.v7.app.ActionBar;
22+
import android.support.v7.app.AppCompatActivity;
23+
import android.view.MenuItem;
24+
25+
/**
26+
* Displays an activity for who you are following
27+
*/
28+
public class FollowingPreferenceActivity extends AppCompatActivity {
29+
30+
@Override
31+
protected void onCreate(Bundle savedInstanceState) {
32+
super.onCreate(savedInstanceState);
33+
setContentView(R.layout.activity_settings);
34+
ActionBar actionBar = this.getSupportActionBar();
35+
36+
// Set the action bar back button to look like an up button
37+
if (actionBar != null) {
38+
actionBar.setDisplayHomeAsUpEnabled(true);
39+
}
40+
}
41+
42+
@Override
43+
public boolean onOptionsItemSelected(MenuItem item) {
44+
int id = item.getItemId();
45+
// When the home button is pressed, take the user back to the MainActivity
46+
if (id == android.R.id.home) {
47+
NavUtils.navigateUpFromSameTask(this);
48+
}
49+
return super.onOptionsItemSelected(item);
50+
}
51+
}

0 commit comments

Comments
 (0)